0

このリンクを参照して 、文字列またはバイト配列の CRC32 を 計算する CRC32 の代わりに CRC16 を計算するためにコードを修正しましたが、間違った結果が得られました。

Private Sub Main()
Crc16.ComputeChecksum(Encoding.UTF8.GetBytes("Some string"))
End Sub
    Public Class CRC16
Shared table As UShort()

Shared Sub New()
    Dim poly As UShort = &HA001US 'calculates CRC-16 using A001 polynomial (modbus)
    table = New UShort(255) {}
    Dim temp As UShort = 0
    For i As UShort = 0 To table.Length - 1
        temp = i
        For j As Integer = 8 To 1 Step -1
            If (temp And 1) = 1 Then
                temp = CUShort((temp >> 1) Xor poly)
            Else
                temp >>= 1
            End If
        Next
        table(i) = temp
    Next
End Sub

Public Shared Function ComputeChecksum(ByVal bytes As Byte()) As UShort
    Dim crc As UShort = &H0US ' The calculation start with 0x00
    For i As Integer = 0 To bytes.Length - 1
        Dim index As Byte = CByte(((crc) And &HFF) Xor bytes(i))
        crc = CUShort((crc >> 8) Xor table(index))
    Next
    Return Not crc
End Function
End Class
4

2 に答える 2

1

これを試してみてください。これは、計測器制御用の VB6 コードです。(sCommand はすべてのバイトを含む一時文字列であり、Result は sCommand に追加されます。Modbus は LSB を最初に使用します。TextToString と StringToAscii は、読み取り可能な文字列「FF EE」を ASCII に変換して戻す関数であるため、ここでは重要ではありません。 ):

Private Sub cmdCRC16_Click()
Dim sCommand As String
Dim x As Long
Dim y As Long
Dim lCRC As Long
sCommand = TextToString(txtASCII)
'Initial value
lCRC = 65535 '(&HFFFF results in Integer -1)
For x = 1 To Len(sCommand)
    lCRC = lCRC Xor Asc(Mid(sCommand, x, 1))
    For y = 1 To 8
        If (lCRC Mod 2) > 0 Then
            lCRC = (lCRC And 65534) / 2
            lCRC = lCRC Xor 40961 '(&HA001 results in whatever negative integer)
        Else
            lCRC = (lCRC And 65534) / 2
        End If
    Next y
Next x
'Add CRC with LSB first
sCommand = sCommand + Chr(lCRC And 255)
sCommand = sCommand + Chr((lCRC And 65280) / 256)
txtASCII = StringToASCII(sCommand)

サブ終了

于 2014-10-28T13:30:17.243 に答える