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?
''' <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
Blizzard has a history of using incorrect implementations of standard algorithms. Does your crc function compute the correct value for published crc test vectors?
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.
http://www.vbaccelerator.com/home/NET/Code/Libraries/CRC32/article.asp
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:
''' <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
[Kp edit: fixed table.]