简体   繁体   English

在Swift中反向CRC-32 NSData

[英]Reverse CRC-32 NSData in Swift

I think the components of the answer are out there, but I don't understand this stuff well enough, and I'm getting very stuck on conversions. 我认为答案的组成部分已经存在,但是我对这方面的知识还不够了解,而且转换非常困难。

Here's an implementation I found for NSData to crc32: 这是我发现的NSData到crc32的实现:

https://github.com/krzyzanowskim/CryptoSwift/blob/643bbabd6781b6e226f18815dba616cf6a08629b/CryptoSwift/CRC.swift https://github.com/krzyzanowskim/CryptoSwift/blob/643bbabd6781b6e226f18815dba616cf6a08629b/CryptoSwift/CRC.swift

Unfortunately, I need a version that has a reverse: 不幸的是,我需要一个与之相反的版本:

This thread seems to come the closest: Reversing CRC32 该线程似乎最接近: 反转CRC32

I've used its logic to create this which generates the two CRC tables: 我已使用其逻辑来创建此逻辑,该逻辑生成了两个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)
}

But, now I'm very stuck on how to take the data and create a reverse crc32: 但是,现在我非常着迷于如何获取数据并创建反向crc32:

func reverseCRC(data: NSData) -> UInt32 {
    var bytes = [UInt8](count: data.length, repeatedValue: 0)
    data.getBytes(&bytes, length:data.length * sizeof(UInt8))


    return 0
}

Update 更新

Through various searching, I have come up with this: 通过各种搜索,我得出了以下结论:

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
}

But, I don't really understand it (particularly the last 2 lines), and I'm unsure how to test its accuracy. 但是,我不太了解它(尤其是最后两行),而且我不确定如何测试其准确性。 If anyone can help in that direction. 如果有人可以朝这个方向提供帮助。

Goal 目标

I have a firmware update that I'm transmitting to hardware via bluetooth, and once all of the data for the firmware update has been transmitted, I submit a validation payload in the form of a: 我有一个固件更新,该固件要通过蓝牙传输到硬件,一旦传输了所有固件更新数据,便以以下形式提交验证有效载荷:

Reversed CRC 32 (Big Endian) CRC反转32(Big Endian)

Reversed CRC 32 (Big Endian) CRC反转32(Big Endian)

That sounds like it simply means a normal CRC-32, sent in big-endian order. 这听起来像只是意味着普通的CRC-32,以big-endian顺序发送。 Most CRC's are generated in bit-reversed order, using a bit-reversed polynomial, since that makes the code a little simpler. 大多数CRC是使用位反转多项式以位反转顺序生成的,因为这会使代码更简单。

The "big endian" part is independent and refers to the fact that once you have a four-byte value, however it may have been generated, you can put it in the byte stream in big or little endian order. “大尾数”部分是独立的,指的是以下事实:一旦有了一个四字节的值(可能已生成),就可以按大尾数顺序或小尾数顺序将其放入字节流。 The specification is to put it in the stream in big-endian order, ie the most significant byte first. 规范是以大端顺序将其放入流中,即,最高有效字节在前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM