-2

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
Womabre
  • 9
  • 1
  • 1
    Do you understand what the code you posted is doing? If not, that's your first objective. Copying code of the web and asking others to write more code for you is not being a programming and this site is for programming issues. If you're not going to put some effort in yourself then there's no actual problem for us to help you with. – jmcilhinney Mar 10 '21 at 23:32

2 Answers2

0

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.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Hi Mark. Thanks for the explanation. I now also have a better understanding of how the CRC32 code works. I added the adapted the code to the post. But I'm getting the following error: System.OverflowException: Arithmetic operation resulted in an overflow. at ThisRule.Crc64.ComputeChecksum(Byte[] bytes) I know this means I'm trying to store data somewhere but it is to large for the type. But I can't figure out where. – Womabre Mar 11 '21 at 11:02
  • Change the `temp And 1` to `temp And 1UL` and the `&Hff` to `&HffUL`. Also you didn't reverse the polynomial. Why did you change 8's to 16's? Put the 8's back. – Mark Adler Mar 11 '21 at 16:52
0
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
Womabre
  • 9
  • 1