【问题标题】:Why does not this Visual basic code produce any results?为什么此 Visual Basic 代码不产生任何结果?
【发布时间】:2014-07-27 12:26:41
【问题描述】:

我在 Visual Basic 中的 Windows 应用程序表单项目中运行此代码。这段代码应该为我提供一个字节数组的 CRC-32 字节,但无论我做什么,我都无法输出任何字节。抱歉,如果我在这里遗漏了一些非常明显的东西,但我已经尝试过“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

【问题讨论】:

  • 如果性能很重要,您应该考虑切换到 SHA256 甚至 MD5 - CRC32 已经过时,甚至不再产生可靠的传输层有效性信息。你真的应该使用至少 MD5,每个人都可以在msdn.microsoft.com/de-de/library/… 上使用它
  • 所有那些 On Error Resume Next 似乎只是为了隐藏错误。并且请将 OPTION STRICT 设置为 ON,当您将 long 转换为整数时,您会在代码中发现很多错误
  • @Steve:如果可以的话,我会对该评论 +10。
  • 谢谢大家。我使用 CRC-32 的原因是我尝试与之通信的设备使用 CRC-32,我需要检查接收到的数组的接收到的 CRC 字节与我试图为字节数组计算的那些字节。至于 OPTION STRICT ON,我将其打开,并没有注意到有关您提到的那些错误的任何特定错误消息。伙计们,如果您能指导我使用功能正常的 CRC-32 代码,我真的很感激,因为我已经尝试了一些,但到目前为止都没有得到任何输出。
  • 您可能希望将您在Sub Main 中放入的代码改为Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load。删除所有那些 On Error Resume Next 行,因为它们没有任何用处。您可以使用>> Operator 右移整数值。

标签: vb.net crc32


【解决方案1】:

有几个问题。首先,所有的 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 函数。 不要从表单加载中调用它从那里开始调试将太困难。添加一个按钮并从 click 事件中调用 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 的记忆一致。另一种方法是相反:将其更改为整数并将Crc32 And &amp;HFF 转换为整数。

请注意,我没有检查任何 CRC32 内容(如表初始化程序),仅检查 OPTION Strict 问题并将其连接起来,并检查初始异常。


附录

我找到了自己的旧 CRC32 代码,在比较时,我发现了一些与 CRC 相关的问题:

Buildtable/InitCrc32 过程中的几乎所有内容,包括返回值应该是整数 (Int32) 而不是长整数 (Int64)。看起来您从 VB6 源代码复制了代码,并且没有正确更新(在任何地方都不需要 Long)。

对于文本编码,您可能想要这样:

Dim encoding As New System.Text.UTF8Encoding()
Dim byt As Byte() = encoding.GetBytes(s)

而不是上面给出的Convert.ToByte。正如我所说,我主要关注的是让它以某种形式或方式工作,而不是验证算法。

【讨论】:

  • 我会使用Return value 而不是FunctionName = value。原文中的一些 cmets 似乎具有误导性,例如'// Right shift an Unsigned Long 8 bits 看起来应该是 ' Right shift by 8 bits and truncate。关于 Form_Load 中的代码难以调试的优点。您的 lIndex 修复给出了与 OP 代码相同的结果。
  • @AndrewMorton 是的,旧样式Returns 和 cmets 是其他指标,源是一些旧的 VB6 代码转换;在 NET 中计算 CRC32 时也过多地使用 Long (Int64)。我根本没有修改他的算法,以免一切都被解开,只是修复了Option Strict 问题并让它开火。不过现在看看 CRC 的东西。
  • System.Text.UTF8Encoding.UTF8.GetBytes 是一个公共共享函数.. 我更喜欢 FunctionName = value .. 当然有布尔返回函数
  • 是的..我的意思是 System.Text.Encoding.UTF8 是公共共享只读属性.. System.Text.Encoding.UTF8.GetBytes(s) 或 System.Text.UTF8Encoding.UTF8 .GetBytes(s) 就足够了
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
  • 2013-10-25
  • 1970-01-01
相关资源
最近更新 更多