Womabre
Womabre

Reputation: 9

CRC64 calculation in VB

I'm using the code I found [here][1] tot calculate a CRC32 checksum. I would also like to calculate a CRC64 checksum. But I can't figure out how to do this. Any help would be appreciated!

Below the code from "Magnus" I'm using for CRC32.

    Private Sub Main()
        Crc32.ComputeChecksum(Encoding.UTF8.GetBytes("Some string")).Dump()
    End Sub
    
    Public Class Crc32
        Shared table As UInteger()
    
        Shared Sub New()
            Dim poly As UInteger = &Hedb88320UI
            table = New UInteger(255) {}
            Dim temp As UInteger = 0
            For i As UInteger = 0 To table.Length - 1
                temp = i
                For j As Integer = 8 To 1 Step -1
                    If (temp And 1) = 1 Then
                        temp = CUInt((temp >> 1) Xor poly)
                    Else
                        temp >>= 1
                    End If
                Next
                table(i) = temp
            Next
        End Sub
    
        Public Shared Function ComputeChecksum(bytes As Byte()) As UInteger
            Dim crc As UInteger = &HffffffffUI
            For i As Integer = 0 To bytes.Length - 1
                Dim index As Byte = CByte(((crc) And &Hff) Xor bytes(i))
                crc = CUInt((crc >> 8) Xor table(index))
            Next
            Return Not crc
        End Function
    End Class

Thanks to Mark Adler I got the code working!

The code bellow produces the following result: CRC64: 995DC9BBDF1939FA

Private Sub Main()
    Try
        MessageBox.Show("CRC64: " & UCase(Hex(CRC64.ComputeChecksum(System.Text.Encoding.UTF8.GetBytes("123456789")))))
    Catch ex As Exception
        MessageBox.Show(ex.ToString)
    End Try
End Sub


Public Class CRC64
    Shared table As ULong()
    Shared Sub New()
        Dim poly As ULong =  &Hc96c5795d7870f42UL
        table = New ULong(255) {}
        Dim temp As ULong = 0
        For i As ULong = 0 To table.Length - 1
            temp = i
            For j As Integer = 8 To 1 Step -1
                If (temp And 1UL) = 1 Then
                    temp = CULng((temp >> 1) Xor poly)
                Else
                    temp >>= 1
                End If
            Next
            table(i) = temp
        Next
    End Sub

    Public Shared Function ComputeChecksum(bytes As Byte()) As ULong
        Dim crc As ULong = &HffffffffffffffffUL
        Dim i As Integer
        For i = 0 To bytes.Length - 1
            Dim index As Byte = CByte(((crc) And &HffUL) Xor bytes(i))
            crc = CULng((crc >> 8) Xor table(index))
        Next i
    Return Not crc
    End Function
End Class

  [1]: https://stackoverflow.com/questions/15553697/calculate-crc32-of-an-string-or-byte-array

Upvotes: -2

Views: 884

Answers (2)

Womabre
Womabre

Reputation: 9

Private Sub Main()
    Try
        MessageBox.Show("CRC64: " & UCase(Hex(CRC64.ComputeChecksum(System.Text.Encoding.UTF8.GetBytes("123456789")))))
    Catch ex As Exception
        MessageBox.Show(ex.ToString)
    End Try
End Sub


Public Class CRC64
    Shared table As ULong()
    Shared Sub New()
        Dim poly As ULong =  &Hc96c5795d7870f42UL
        table = New ULong(255) {}
        Dim temp As ULong = 0
        For i As ULong = 0 To table.Length - 1
            temp = i
            For j As Integer = 8 To 1 Step -1
                If (temp And 1UL) = 1 Then
                    temp = CULng((temp >> 1) Xor poly)
                Else
                    temp >>= 1
                End If
            Next
            table(i) = temp
        Next
    End Sub

    Public Shared Function ComputeChecksum(bytes As Byte()) As ULong
        Dim crc As ULong = &HffffffffffffffffUL
        Dim i As Integer
        For i = 0 To bytes.Length - 1
            Dim index As Byte = CByte(((crc) And &HffUL) Xor bytes(i))
            crc = CULng((crc >> 8) Xor table(index))
        Next i
    Return Not crc
    End Function
End Class

Upvotes: 0

Mark Adler
Mark Adler

Reputation: 112627

First you need to find a CRC-64 description to implement. You don't just want to pick a random polynomial. This one, CRC-64/XZ, from here would be easiest to convert your implementation to:

width=64 poly=0x42f0e1eba9ea3693 init=0xffffffffffffffff refin=true refout=true xorout=0xffffffffffffffff check=0x995dc9bbdf1939fa residue=0x49958c9abd7d353f name="CRC-64/XZ"

You need to take that poly and reverse the 64 bits to use as your poly. You need to use ULong instead of UInteger types in the calculation to hold 64 bits. You need to have twice as many fs for that all-ones value in 64 bits. Then you should be good to go.

Check your code by replacing "Some string" with "123456789" and see if you get the check= value in the CRC definition above.

Upvotes: 0

Related Questions