Reputation: 9
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
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
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 f
s 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