I have a form where I'm extracting some text and hex data from elements in an xml file, this is working great for the text and hex so far but I am trying to calculate the CRC32 for a string of hex data that's in a label.text control.
I'm getting a result in the label but the hex value is that of a string (i'm using an online CRC32 generator to compare the results) when I select the input data to bytes I get the correct checksum that matches the checksum in the original xml file, when I select string in the online form I get the same value that appears on my form.
我有一个表格,我从xml文件中的元素中提取一些文本和十六进制数据,到目前为止,这对文本和十六进制数据非常有效,但我试图计算一个标签中十六进制数据字符串的CRC 32。我在标签中得到一个结果,但十六进制值是一个字符串(我使用在线CRC 32生成器来比较结果)当我选择输入数据到字节时,我得到了与原始XML文件中的校验和相匹配的正确校验和,当我在在线表单中选择字符串时,我得到了与表单上显示的相同的值。
How can I send the label.text data to the crc32 class in the right format to get the same answer as the online form when bytes is selected, I've tried converting to hex but I just can't seem to get it to work.
如何以正确的格式将Label.Text数据发送到crc32类,以获得与在线表单相同的结果。如果选择了字节,我已尝试转换为十六进制,但似乎无法正常工作。
This is the hex (Motorola format) I want the CRC32 for
4230343100000213FCE60143FEBB06ABFF9A009A0033FFCD07E1FFFFFF07AE0666066607AE400040004000400008000800080008000116CF0D57180000FB01BA000602050000FFEE0029001B003722004C000000000000000000000000000000000000000000051A051A031A031AFEE6FEE6FCE6FCE67FFF7FFF002040200600004000240610384001040080400080001002000060200000000300000000000000000000000000000000000000000000000000004000000000000B8333535A47000000000D1C201A4259363334464C5800000000000000000000000000000000000000000000000000000000000000000030402407000042007606103840050C008060208002300240006021001E40030000000000000000000000000000000000000000000000000000000000000000000000000000000050484556138812CA11BC10360F960F1E0EB00E740E4C0E240DF70DCA0DAC61A861A861A861A861A861A859D83B603A983A983A983A983A9800000000000000000000000000000000010102000000001400
这是十六进制的(摩托罗拉格式)我想要用于4230343100000213FCE60143FEBB06ABFF9A009A0033FFCD07E1FFFFFF07AE0666066607AE400040004000400008000800080008000116CF0D57180000FB01BA000602050000FFEE0029001B003722004C000000000000000000000000000000000000000000051A051A031A031AFEE6FEE6FCE6FCE67FFF7FFF002040200600004000240610384001040080400080001002000060200000000300000000000000000000000000000000000000000000000000004000000000000B8333535A47000000000D1C201A4259363334464C5800000000000000000000000000000000000000000000000000000000000000000030402407000042007606103840050C008060208002300240006021001E40030000000000000000000000000000000000000000000000000000000000000000000000000000000050484556138812CA11BC10360F960F1E0EB00E740E4C0E240DF70DCA0DAC61A861A861A861A861A861A859D83B603A983A983A983A983A9800000000000000000000000000000000010102000000001400的CRC32
This is the CRC32 HEX result I need
6889CDCF
这是CRC32十六进制结果,我需要6889CDCF
Here is the Crc32 code I got from this forum: -
这是我从这个论坛上得到的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
Here is the code I'm using
以下是我正在使用的代码
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
This is the online CRC32 generator and the result is what I'm trying to get in my form.
这是在线CRC32生成器,结果就是我想要在表单中得到的结果。
Online CRC result for Byte
字节的在线CRC结果
but I get this result in my VB form
但是我在我的VB表单中得到了这个结果
Online CRC result for string
字符串的在线CRC结果
I realise it's probably down to my lack of understanding in data types as I'm only a self taught amateur!
我意识到这可能是因为我对数据类型缺乏理解,因为我只是一个自学成才的业余爱好者!
Thanks for any help.
谢谢你的帮助。
I've tried to do type conversion to see if I can send in a byte format but it doesn't help
我试着进行类型转换,看看是否能以字节格式发送,但无济于事
更多回答
You don't want to be calling Encoding.GetBytes. That would be if you had text that represented words. In this case, you have hexadecimal data that represents bytes. You should be calling Convert.ToByte for each pair of hex digits and then feeding the resulting Bytes in to your CRC algorithm.
您不希望调用Encoding.GetBytes。这是如果你有代表单词的文本的话。在本例中,您拥有表示字节的十六进制数据。您应该为每对十六进制数字调用Convert.ToByte,然后将生成的Bytes提供给您的CRC算法。
As @jmcihinney already mentioned, convert the string to a byte array first. I made a little test program with your code fragments and it results in the expected CRC:
正如@jmcihinney已经提到的,首先将字符串转换为字节数组。我用您的代码片段做了一个小测试程序,它产生了预期的CRC:
Imports System
Module Program
Sub Main(args As String())
Dim testString As String = "4230343100000213FCE60143FEBB06ABFF9A009A0033FFCD07E1FFFFFF07AE0666066607AE400040004000400008000800080008000116CF0D57180000FB01BA000602050000FFEE0029001B003722004C000000000000000000000000000000000000000000051A051A031A031AFEE6FEE6FCE6FCE67FFF7FFF002040200600004000240610384001040080400080001002000060200000000300000000000000000000000000000000000000000000000000004000000000000B8333535A47000000000D1C201A4259363334464C5800000000000000000000000000000000000000000000000000000000000000000030402407000042007606103840050C008060208002300240006021001E40030000000000000000000000000000000000000000000000000000000000000000000000000000000050484556138812CA11BC10360F960F1E0EB00E740E4C0E240DF70DCA0DAC61A861A861A861A861A861A859D83B603A983A983A983A983A9800000000000000000000000000000000010102000000001400"
Dim byteArray As Byte() = Hex.ToByteArray(testString)
Dim result As UInt32 = Crc32.ComputeChecksum(byteArray)
Dim stringResult As String = result.ToString("X8") '6889CDCF
End Sub
End Module
Public Class Hex
Public Shared Function ToByteArray(hexString As String) As Byte()
If (hexString Is Nothing) Then Throw New ArgumentNullException(NameOf(hexString))
hexString = hexString.Trim()
If (hexString.Length Mod 2) = 1 Then Throw New ArgumentException($"Invalid hex string: an even number of characters expected! Actual: {hexString.Length}")
Dim result((hexString.Length \ 2) - 1) As Byte
Dim readIndex As Int32 = 0
Dim readIndexMax As Int32 = hexString.Length - 2
Dim writeIndex As Int32 = 0
Dim hexChar As String = Nothing
Try
Do While (readIndex <= readIndexMax)
hexChar = hexString.Substring(readIndex, 2)
result(writeIndex) = Convert.ToByte(hexChar, 16)
readIndex += 2
writeIndex += 1
Loop
Catch ex As Exception
Throw New ArgumentException($"Invalid hex string at index {readIndex} ('{hexChar}')!")
End Try
Return result
End Function
End Class
Public Class Crc32
Private Shared ReadOnly _Table As UInt32()
Shared Sub New()
Dim poly As UInt32 = &HEDB88320UI
_Table = New UInt32(255) {}
For i As Int32 = 0 To _Table.Length - 1
Dim temp As UInt32 = CUInt(i)
For j As Int32 = 8 To 1 Step -1
If (temp And 1) = 1 Then
temp = (temp >> 1) Xor poly
Else
temp >>= 1
End If
Next
_Table(i) = temp
Next
End Sub
Public Shared Function ComputeChecksum(bytes As Byte()) As UInt32
Dim crc As UInt32 = &HFFFFFFFFUI
For i As Int32 = 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
I also slightly optimized the Crc32 code to have less casts...
我还略微优化了Crc32代码,以减少强制转换...
更多回答
(As of .NET 5, you can use Convert.FromHexString
instead of your ToByteArray
function.)
(从.NET 5开始,您可以使用Convert.FromHexString而不是ToByteArray函数。)
OMG! thanks so much for this info. I was trying to change what I was sending to the Crc32 to the right format but nothing I tried worked, I just don't have the knowledge. Thanks to you both for taking the time to help me :-)
天哪!非常感谢你给我这个信息。我试图将我发送给Crc32的内容更改为正确的格式,但我尝试的都不起作用,我只是不知道。感谢你们两位花时间帮助我:-)
我是一名优秀的程序员,十分优秀!