Расчет CRC64 в VB

Я использую код, который нашел [здесь][1], чтобы вычислить контрольную сумму CRC32. Я также хотел бы вычислить контрольную сумму CRC64. Но я не могу понять, как это сделать. Любая помощь будет оценена по достоинству!

Ниже приведен код от "Магнуса", который я использую для 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

Благодаря Марку Адлеру код заработал!

Приведенный ниже код дает следующий результат: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

2 ответа

Сначала вам нужно найти описание CRC-64 для реализации. Вы не просто хотите выбрать случайный многочлен. Вот этот, CRC-64 / XZ, отсюда проще всего преобразовать вашу реализацию в:

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

Вам нужно взять это и перевернуть 64 бита, чтобы использовать его в качестве своего poly. Вам нужно использовать ULong вместо UIntegerтипы в расчете для хранения 64 бит. Вам нужно иметь вдвое больше fs для этого универсального значения в 64 бита. Тогда тебе должно быть хорошо.

Проверьте свой код, заменив "Some string" с "123456789" и посмотрите, получите ли вы check= значение в определении CRC выше.

      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
Другие вопросы по тегам