Author | Message | Time |
---|---|---|
Strilanc | I'm trying to compute the crc32 (I believe that's what it is, 4 bytes, and changes radically when the map is re-saved) for wc3 maps (I'm using icewind v2.05 for my tests). I implemented the IEEE crc32 but my results aren't matching. According to the sniffed statstring, I should be getting "7E BF CB 09", but I get "7C BB 83 D8". Is there some kind of quirk I need to put in? Am I using the right polynomial? [code] ''' <summary>Computes the crc32 value for a stream of data.</summary> ''' <param name="s">The stream to read data from.</param> ''' <param name="poly">The polynomial to be used, specified in a bit pattern. (Default is CRC-32-IEEE 802.3).</param> ''' <returns>crc32 value</returns> Public Shared Function crc32(ByVal s As Stream, Optional ByVal poly As UInteger = &H4C11DB7) As UInteger Dim r As New BinaryReader(s) 'Precompute the combined XOR masks for each byte Dim xorTable(0 To 255) As UInteger For i As Integer = 0 To 255 Dim regb As Byte = CByte(i) For j As Integer = 7 To 0 Step -1 xorTable(i) = xorTable(i) Xor ((poly << j) * (regb >> 7)) regb = (regb << 1) Xor CByte((poly >> 24) * (regb >> 7)) Next j Next i 'Direct Table Algorithm Dim reg As UInteger = 0 For i As Long = 0 To s.Length - 1 - s.Position reg = (reg << 8) Xor xorTable(CInt((reg >> 24) Xor r.ReadByte())) Next i Return reg End Function [/code] | January 12, 2008, 3:33 AM |
Kp | Blizzard has a history of using incorrect implementations of standard algorithms. Does your crc function compute the correct value for published crc test vectors? | January 12, 2008, 3:54 AM |
Strilanc | You might have found the problem. Do you see any problems with my algorithm? I had to write it because there's no given crc32 in .net. The output doesn't seem to match test strings, but I don't even know if they're using the same polynomial. | January 12, 2008, 1:28 PM |
St0rm.iD | http://www.vbaccelerator.com/home/NET/Code/Libraries/CRC32/article.asp | January 12, 2008, 5:36 PM |
Strilanc | After messing with my function for quite awhile, I managed to get it right. Well, almost. It turns out the data I was trying to match was not a standard crc32. However, another DWORD I needed to figure out matched the output and it turns out that one IS a standard crc32! :D Source code for others: [code] ''' <summary>Computes the crc32 value for a stream of data.</summary> ''' <param name="s">The stream to read data from.</param> ''' <param name="poly">The polynomial to be used, specified in a bit pattern. (Default is CRC-32-IEEE 802.3).</param> ''' <returns>crc32 value</returns> Public Shared Function crc32(ByVal s As Stream, Optional ByVal poly As UInteger = &H4C11DB7, Optional ByVal polyIsReversed As Boolean = False) As UInteger Dim r As New BinaryReader(s) Dim reg As UInteger 'Reverse the polynomial If polyIsReversed = False Then Dim polyRev As UInteger = 0 For i As Integer = 0 To 31 If ((poly >> i) And &H1) <> 0 Then polyRev = polyRev Or (CUInt(&H1) << (31 - i)) End If Next i poly = polyRev End If 'Precompute the combined XOR masks for each byte Dim xorTable(0 To 255) As UInteger For i As Integer = 0 To 255 reg = CUInt(i) For j As Integer = 0 To 7 If (reg And CUInt(&H1)) <> 0 Then reg = (reg >> 1) Xor poly Else reg >>= 1 End If Next j xorTable(i) = reg Next i 'Direct Table Algorithm reg = Not CUInt(0) For i As Long = 0 To s.Length - s.Position - 1 reg = (reg >> 8) Xor xorTable(r.ReadByte() Xor CByte(reg And &HFF)) Next i Return Not reg End Function [/code] [Kp edit: fixed table.] | January 18, 2008, 9:50 PM |