title: Reverse CRC-32 NSData in Swift
body: <p>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.</p>
  
  <p>Here's an implementation I found for NSData to crc32:</p>
  
  <p><a href="https://github.com/krzyzanowskim/CryptoSwift/blob/643bbabd6781b6e226f18815dba616cf6a08629b/CryptoSwift/CRC.swift" rel="nofollow noreferrer">https://github.com/krzyzanowskim/CryptoSwift/blob/643bbabd6781b6e226f18815dba616cf6a08629b/CryptoSwift/CRC.swift</a></p>
  
  <p>Unfortunately, I need a version that has a reverse:</p>
  
  <p>This thread seems to come the closest: <a href="https://stackoverflow.com/q/1514040/2611971">Reversing CRC32</a></p>
  
  <p>I've used its logic to create this which generates the two CRC tables:</p>
  
  <pre><code>func crcTables() -&gt; (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 &lt;&lt; (3 * 8)
  
          for _ in 1...8 {
              if (forward &amp; 1) == 1 {
                  forward = (forward &gt;&gt; 1) ^ poly
              } else {
                  forward &gt;&gt;= 1
              }
  
              if (reverse &amp; 0x80000000) != 0 {
                  reverse = ((reverse ^ poly) &lt;&lt; 1) | 1
              } else {
                  reverse &lt;&lt;= 1
              }
          }
  
          forwardTable.append(forward)
          reverseTable.append(reverse)
      }
  
      return (forwardTable, reverseTable)
  }
  </code></pre>
  
  <p>But, now I'm very stuck on how to take the data and create a reverse crc32:</p>
  
  <pre><code>func reverseCRC(data: NSData) -&gt; UInt32 {
      var bytes = [UInt8](count: data.length, repeatedValue: 0)
      data.getBytes(&amp;bytes, length:data.length * sizeof(UInt8))
  
  
      return 0
  }
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>Through various searching, I have come up with this:</p>
  
  <pre><code>func reverseCRC32WithData(data: NSData, wantedCRC: UInt32 = 0) -&gt; UInt32 {
      var reversedCRC = wantedCRC
  
      var bytes = [UInt8](count: data.length, repeatedValue: 0)
      data.getBytes(&amp;bytes, length:data.length * sizeof(UInt8))
  
      // Drop trailing 1 if exists
      let bufferLength = (data.length &gt;&gt; 1) &lt;&lt; 1
  
      for i in 0.stride(to: bufferLength + 4, by: sizeof(UInt16)) {
          var word: UInt16 = 0x0000
          if i &lt; bufferLength {
              let b1 = bytes[bufferLength - 2 - i]
              let b2 = bytes[bufferLength - 1 - i]
              word = (UInt16(b1) &lt;&lt; 8) | UInt16(b2)
          } else {
              word = 0xffff
          }
  
          reversedCRC = ((reversedCRC &lt;&lt; 8) &amp; 0xffffffff) ^ ReverseTable[Int((reversedCRC &gt;&gt; 24) &amp; 0xff)] ^ (UInt32(word) &gt;&gt; 8) &amp; 0xff
          reversedCRC = ((reversedCRC &lt;&lt; 8) &amp; 0xffffffff) ^ ReverseTable[Int((reversedCRC &gt;&gt; 24) &amp; 0xff)] ^ (UInt32(word) &amp; 0xff)
      }
  
      return reversedCRC
  }
  </code></pre>
  
  <p>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.</p>
  
  <p><strong>Goal</strong></p>
  
  <p>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:</p>
  
  <blockquote>
    <p>Reversed CRC 32 (Big Endian)</p>
  </blockquote>