VB.NET 计算字符串或字节数组的 CRC16 的示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23009036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 17:20:19  来源:igfitidea点击:

example for VB.NET to calculate CRC16 of an string or Byte Array

vb.netcrc16

提问by H. Saffour

With reference to this link Calculate CRC32 of an String or Byte ArrayI modified the code in order to calculate the CRC16 instead of CRC32, however I am getting wrong result, can some one point me where is the mistake?

参考这个链接 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

回答by Andy

Try this, it's working VB6 code for Instrument control. (sCommand is a temp string which contains all Bytes, Result is added to sCommand, Modbus is using LSB first, TextToString and StringToAscii are functions to convert a readable string "FF EE" into ASCII and back, thus they are not of interest here.):

试试这个,它是用于仪器控制的 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

结束子

回答by Bitshift

I just came accross the same issue. Simple solution is to omit negation at the end, so just change your "Return Not crc" to "Return crc" and you be fine.

我刚刚遇到了同样的问题。简单的解决方案是在最后省略否定,所以只需将“Return Not crc”更改为“Return crc”就可以了。

There are various variants of CRC-16, where "CRC-16" notmally refers to the IBM variant, also called "ARC". It uses an XorOut value of zero. See Catalogue of parametrised CRC algorithms with 16 bits.

CRC-16 有多种变体,其中“CRC-16”通常指的是 IBM 变体,也称为“ARC”。它使用零的 XorOut 值。请参阅16 位参数化 CRC 算法目录