我在Visual Basic的Windows Application Form项目中运行此代码。这段代码应该给我一个字节数组的CRC-32字节,但无论我做什么我都不能输出任何字节。对不起,如果有一些非常明显我在这里丢失的东西,但我已经尝试了#34; MsgBox","立即屏幕"使用" debug.print"我也尝试在文本框中打印字节,但没有结果。如果你能帮助我,我感激不尽。
Public Class Form1
Public Sub Main()
Dim lCrc32Value As Long
On Error Resume Next
lCrc32Value = InitCrc32()
lCrc32Value = AddCrc32("This is the original message!", _
lCrc32Value)
'Debug.Print(Hex$(GetCrc32(lCrc32Value)))
TextBox1.Text = (Hex$(GetCrc32(lCrc32Value))).ToString
End Sub
'// Then declare this array variable Crc32Table
Private Crc32Table(255) As Long
'// Then all we have to do is write public functions like
'these...
Public Function InitCrc32(Optional ByVal Seed As Long = _
&HEDB88320, Optional ByVal Precondition As _
Long = &HFFFFFFFF) As Long
'// Declare counter variable iBytes,
'counter variable iBits,
'value variables lCrc32 and lTempCrc32
Dim iBytes As Integer, iBits As Integer, lCrc32 As Long
Dim lTempCrc32 As Long
'// Turn on error trapping
On Error Resume Next
'// Iterate 256 times
For iBytes = 0 To 255
'// Initiate lCrc32 to counter variable
lCrc32 = iBytes
'// Now iterate through each bit in counter byte
For iBits = 0 To 7
'// Right shift unsigned long 1 bit
lTempCrc32 = lCrc32 And &HFFFFFFFE
lTempCrc32 = lTempCrc32 \ &H2
lTempCrc32 = lTempCrc32 And &H7FFFFFFF
'// Now check if temporary is less than zero and then
'mix Crc32 checksum with Seed value
If (lCrc32 And &H1) <> 0 Then
lCrc32 = lTempCrc32 Xor Seed
Else
lCrc32 = lTempCrc32
End If
Next
'// Put Crc32 checksum value in the holding array
Crc32Table(iBytes) = lCrc32
Next
'// After this is done, set function value to the
'precondition value
InitCrc32 = Precondition
End Function
'// The function above is the initializing function, now
'we have to write the computation function
Public Function AddCrc32(ByVal Item As String, _
ByVal Crc32 As Long) As Long
'// Declare following variables
Dim bCharValue As Byte, iCounter As Integer, lIndex As Long
Dim lAccValue As Long, lTableValue As Long
'// Turn on error trapping
On Error Resume Next
'// Iterate through the string that is to be checksum-computed
For iCounter = 1 To Len(Item)
'// Get ASCII value for the current character
bCharValue = Asc(Mid$(Item, iCounter, 1))
'// Right shift an Unsigned Long 8 bits
lAccValue = Crc32 And &HFFFFFF00
lAccValue = lAccValue \ &H100
lAccValue = lAccValue And &HFFFFFF
'// Now select the right adding value from the
'holding table
lIndex = Crc32 And &HFF
lIndex = lIndex Xor bCharValue
lTableValue = Crc32Table(lIndex)
'// Then mix new Crc32 value with previous
'accumulated Crc32 value
Crc32 = lAccValue Xor lTableValue
Next
'// Set function value the the new Crc32 checksum
AddCrc32 = Crc32
End Function
'// At last, we have to write a function so that we
'can get the Crc32 checksum value at any time
Public Function GetCrc32(ByVal Crc32 As Long) As Long
'// Turn on error trapping
On Error Resume Next
'// Set function to the current Crc32 value
GetCrc32 = Crc32 Xor &HFFFFFFFF
End Function
'// And for testing the routines above...
End Class
答案 0 :(得分:2)
有几个问题。首先,所有CRC代码都应该在不与表单混合的类中。其次,Option Strict没有打开,因为有几个隐式转换可能会破坏结果:
' converting Integer to Byte
bCharValue = Asc(Mid$(Item, iCounter, 1))
' see note 7
DIm lIndex As Long
' converting integer to Long
lIndex = Crc32 And &HFF
' here too:
lTableValue = Crc32Table(lIndex)
#3。摆脱On Error Resume next
。这不是错误处理 - 它隐藏了你的错误。
#4。你永远不会调用Main函数。 不要从表单加载调用它将从那里调试太困难。添加一个按钮并从点击事件中调用Main。
#5强烈建议从旧的VB函数迁移到.NET中的等效函数,这些函数更加健壮。
#6。对AddCRC32的更改:
Public Function AddCrc32(ByVal Item As String, ByVal Crc32 As Long) As Long
'// Declare following variables
Dim bCharValue As Byte, iCounter As Integer, lIndex As Long
Dim lAccValue As Long, lTableValue As Long
' convert text to char array all at once
Dim strChars = Item.ToCharArray
'// Iterate through the string that is to be checksum-computed
For iCounter = 0 To Item.Length - 1
'// Get ASCII value for the current character
'bCharValue = Asc(Mid$(Item, iCounter, 1))
' NET version
bCharValue = Convert.ToByte(strChars(iCounter))
'// Right shift an Unsigned Long 8 bits
lAccValue = Crc32 And &HFFFFFF00
lAccValue = lAccValue \ &H100
lAccValue = lAccValue And &HFFFFFF
'// Now select the right adding value from the
'holding table
lIndex = Crc32 And &HFF
lIndex = lIndex Xor bCharValue
lTableValue = Crc32Table(CInt(lIndex))
'// Then mix new Crc32 value with previous
'accumulated Crc32 value
Crc32 = lAccValue Xor lTableValue
Next
'// Set function value the the new Crc32 checksum
' a REALLY big indicator that this came from VB6:
AddCrc32 = Crc32
' NET is usually:
' Return Crc32
End Function
#7:上面的lIndex修复应该是我记得的CRC32。另一种方法是反过来:将其更改为Integer并将Crc32 And &HFF
转换为整数。
注意,我没有检查任何CRC32内容(比如表初始化程序),只检查OPTION Strict问题并将其挂起,并检查初始异常。
附录
我找到了自己的旧CRC32代码,在比较时,我发现了一些与CRC相关的问题:
Buildtable/InitCrc32
过程中的几乎所有内容(包括返回值都应该是Integer(Int32)不长(Int64))。看起来您从VB6源代码复制了代码并且没有正确更新(在任何地方都不需要Long
)。
对于文本编码,您可能需要这样:
Dim encoding As New System.Text.UTF8Encoding()
Dim byt As Byte() = encoding.GetBytes(s)
而不是上面给出的Convert.ToByte
。正如我所说,我主要考虑的是以某种形式或方式使其工作,而不是对算法进行认证。