参考此链接计算字符串或字节数组的CRC32我修改了代码,以便计算CRC16而不是CRC32,然而我得到了错误的结果,有人能告诉我错误在哪里吗?
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
试试这个,它正在为仪器控制工作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)
结束子
我刚刚遇到了同样的问题。简单的解决方案是在结尾省略否定,所以只需更改你的"Return Not crc";至";返回crc";你会好起来的。
CRC-16有各种变体;CRC-16";通常指的是IBM变体;ARC";。它使用的XorOut值为零。参见16位参数化CRC算法目录。