【发布时间】:2016-03-12 12:03:52
【问题描述】:
我认为答案的组成部分已经存在,但我对这些东西的理解还不够透彻,而且我在转换上非常卡住。
这是我找到的 NSData 到 crc32 的实现:
不幸的是,我需要一个反向的版本:
这个帖子似乎是最接近的:Reversing CRC32
我已经使用它的逻辑来创建它,它会生成两个 CRC 表:
func crcTables() -> (forwardTable: [UInt32], reverseTable: [UInt32]) {
let poly: UInt32 = 0xedb88320;
var forwardTable: [UInt32] = []
var reverseTable: [UInt32] = []
var forward: UInt32 = 0
var reverse: UInt32 = 0
for i in 0...UInt32(UInt8.max) {
forward = i
reverse = i << (3 * 8)
for _ in 1...8 {
if (forward & 1) == 1 {
forward = (forward >> 1) ^ poly
} else {
forward >>= 1
}
if (reverse & 0x80000000) != 0 {
reverse = ((reverse ^ poly) << 1) | 1
} else {
reverse <<= 1
}
}
forwardTable.append(forward)
reverseTable.append(reverse)
}
return (forwardTable, reverseTable)
}
但是,现在我非常纠结于如何获取数据并创建反向 crc32:
func reverseCRC(data: NSData) -> UInt32 {
var bytes = [UInt8](count: data.length, repeatedValue: 0)
data.getBytes(&bytes, length:data.length * sizeof(UInt8))
return 0
}
更新
通过各种搜索,我想出了这个:
func reverseCRC32WithData(data: NSData, wantedCRC: UInt32 = 0) -> UInt32 {
var reversedCRC = wantedCRC
var bytes = [UInt8](count: data.length, repeatedValue: 0)
data.getBytes(&bytes, length:data.length * sizeof(UInt8))
// Drop trailing 1 if exists
let bufferLength = (data.length >> 1) << 1
for i in 0.stride(to: bufferLength + 4, by: sizeof(UInt16)) {
var word: UInt16 = 0x0000
if i < bufferLength {
let b1 = bytes[bufferLength - 2 - i]
let b2 = bytes[bufferLength - 1 - i]
word = (UInt16(b1) << 8) | UInt16(b2)
} else {
word = 0xffff
}
reversedCRC = ((reversedCRC << 8) & 0xffffffff) ^ ReverseTable[Int((reversedCRC >> 24) & 0xff)] ^ (UInt32(word) >> 8) & 0xff
reversedCRC = ((reversedCRC << 8) & 0xffffffff) ^ ReverseTable[Int((reversedCRC >> 24) & 0xff)] ^ (UInt32(word) & 0xff)
}
return reversedCRC
}
但是,我不太了解它(尤其是最后两行),我不确定如何测试它的准确性。如果有人可以在这个方向上提供帮助。
目标
我有一个固件更新,我通过蓝牙传输到硬件,一旦固件更新的所有数据都传输完毕,我会提交一个验证负载,格式为:
逆向 CRC 32(大端)
【问题讨论】:
-
“反向”是什么意思?
-
@MarkAdler 不幸的是,我不完全确定。底部的最后一句话是我从文档中得到的。