参考此链接 Calculate CRC32 of an String or Byte Array 我修改了代码以便计算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
答案 0 :(得分:1)
试试这个,它正在使用VB6代码进行仪器控制。 (sCommand是包含所有字节的临时字符串,结果添加到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)
End Sub
答案 1 :(得分:0)
我刚刚遇到同样的问题。简单的解决方案是在最后省略否定,所以只需改变你的" Return Not crc"到"返回crc"你没事。
CRC-16有各种变体,其中" CRC-16"通常是指IBM变体,也称为" ARC"。它使用XorOut值为零。请参阅Catalogue of parametrised CRC algorithms with 16 bits。