如何将十六进制字符串转为字节数组计算正确的CRC32校验值?
问题:十六进制字符串转字节数组计算CRC32不匹配目标值
开发的窗体程序可从XML文件提取十六进制数据,但计算CRC32校验值时遇到问题:使用Encoding.UTF8.GetBytes将十六进制字符串转为字节传入Crc32类,得到的结果与在线CRC32工具「字符串」输入的结果一致,但需要的是工具选择「字节」输入时的结果(匹配原XML中的校验值6889CDCF),目前无法将十六进制字符串转为正确的字节格式传入Crc32类。
待计算的Motorola格式十六进制字符串
4230343100000213FCE60143FEBB06ABFF9A009A0033FFCD07E1FFFFFF07AE0666066607AE400040004000400008000800080008000116CF0D57180000FB01BA000602050000FFEE0029001B003722004C000000000000000000000000000000000000000000051A051A031A031AFEE6FEE6FCE6FCE67FFF7FFF002040200600004000240610384001040080400080001002000060200000000300000000000000000000000000000000000000000000000000004000000000000B8333535A47000000000D1C201A4259363334464C5800000000000000000000000000000000000000000000000000000000000000000030402407000042007606103840050C008060208002300240006021001E40030000000000000000000000000000000000000000000000000000000000000000000000000000000050484556138812CA11BC10360F960F1E0EB00E740E4C0E240DF70DCA0DAC61A861A861A861A861A861A859D83B603A983A983A983A983A9800000000000000000000000000000000010102000000001400
目标CRC32十六进制结果
6889CDCF
当前使用的Crc32类代码
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
当前计算代码
If xmlR.NodeType = XmlNodeType.Element AndAlso xmlR.Name = "DATEN" Then HexData = xmlR.ReadElementContentAsString LblRawhex.Text = Microsoft.VisualBasic.Left(HexData, 8) LblDataNmeHex.Text = Microsoft.VisualBasic.Mid(HexData, 9, 24) TxtFullHex.Text = Microsoft.VisualBasic.Left(HexData, Len(HexData) - 8) LblCRC.Text = Hex(Crc32.ComputeChecksum(Encoding.UTF8.GetBytes(TxtFullHex.Text))) 'LblCRC.Text = Crc32.ComputeChecksum(Hex(TxtFullHex.Text)) End If
解决方案
问题核心是:你当前把十六进制字符串作为UTF-8文本转成字节数组,而实际需要把十六进制字符串解析为对应的原始字节(比如字符串中的"42"对应字节0x42)。
1. 实现十六进制字符串转字节数组的函数
添加一个工具函数,将十六进制字符串转换为对应的字节数组:
Public Function HexStringToByteArray(hexString As String) As Byte() ' 移除字符串中所有非十六进制字符(如空格、换行等,若你的字符串无此类字符可省略) hexString = System.Text.RegularExpressions.Regex.Replace(hexString, "[^0-9A-Fa-f]", "") ' 验证字符串长度为偶数,否则无法完整解析为字节 If hexString.Length Mod 2 <> 0 Then Throw New ArgumentException("十六进制字符串长度必须为偶数") End If Dim byteArray(hexString.Length \ 2 - 1) As Byte For i As Integer = 0 To hexString.Length - 1 Step 2 ' 每两个字符解析为一个字节 byteArray(i \ 2) = Convert.ToByte(hexString.Substring(i, 2), 16) Next Return byteArray End Function
2. 修改CRC计算代码
将原来的Encoding.UTF8.GetBytes替换为上述函数,重新计算CRC:
If xmlR.NodeType = XmlNodeType.Element AndAlso xmlR.Name = "DATEN" Then HexData = xmlR.ReadElementContentAsString LblRawhex.Text = Microsoft.VisualBasic.Left(HexData, 8) LblDataNmeHex.Text = Microsoft.VisualBasic.Mid(HexData, 9, 24) TxtFullHex.Text = Microsoft.VisualBasic.Left(HexData, Len(HexData) - 8) ' 使用自定义函数转换十六进制字符串为字节数组 Dim rawBytes As Byte() = HexStringToByteArray(TxtFullHex.Text) ' 计算CRC并转为十六进制字符串 LblCRC.Text = Hex(Crc32.ComputeChecksum(rawBytes)).ToUpper() End If
验证
使用上述代码转换给定的十六进制字符串后,传入Crc32.ComputeChecksum得到的结果即为目标值6889CDCF。
内容的提问来源于stack exchange,提问作者gadjet
相关产品推荐
相关产品推荐

