• Welcome to Valhalla Legends Archive.
 

WC3 Map CRC32 for statstring

Started by Strilanc, January 11, 2008, 09:33 PM

Previous topic - Next topic

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?


    ''' <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
Don't pay attention to this signature, it's contradictory.

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?
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

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.
Don't pay attention to this signature, it's contradictory.


Strilanc

#4
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.]
Don't pay attention to this signature, it's contradictory.