Почему этот код Visual Basic не дает никаких результатов?

Я запускаю этот код в проекте формы приложения Windows в Visual Basic. Этот код должен дать мне байты 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

person Jamy codes    schedule 27.07.2014    source источник
comment
вам следует подумать о переходе на SHA256 или, возможно, даже на MD5, если важна производительность - CRC32 сильно устарел и даже больше не дает надежной информации о достоверности транспортного уровня. Вам действительно следует использовать ПО КРАЙНЕЙ МЕРЕ MD5, который доступен для всех по адресу msdn.microsoft.com/de-de/library/   -  person specializt    schedule 27.07.2014
comment
Кажется, что все эти On Error Resume Next существуют только для того, чтобы скрыть ошибки. И, пожалуйста, установите OPTION STRICT ON, и вы обнаружите много ошибок в своем коде при преобразовании длинных чисел в целые числа.   -  person Steve    schedule 27.07.2014
comment
@Steve: я бы +10 к этому комментарию, если бы мог.   -  person The Blue Dog    schedule 27.07.2014
comment
Спасибо, парни. Причина, по которой я использую CRC-32, заключается в том, что устройство, с которым я пытаюсь связаться, использует CRC-32, и мне нужно сверить полученные байты CRC полученного массива с теми, которые я пытаюсь вычислить для массива байтов. Что касается OPTION STRICT ON, то я его включил и не заметил особых сообщений об ошибках, касающихся тех ошибок, которые вы упомянули. Ребята, я очень признателен, если вы направите меня к функционирующему коду CRC-32, потому что я попробовал несколько и пока не получил никакого результата.   -  person Jamy codes    schedule 27.07.2014
comment
Вероятно, вам нужен код, который вы поместили в Sub Main вместо Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load. Удалите все эти строки On Error Resume Next, так как они не приносят никакой пользы. И вы можете использовать ›› оператор для сдвига интеграла вправо стоимость.   -  person Andrew Morton    schedule 27.07.2014
comment
+1 за все, что сказал @AndrewMorton, кроме использования Form Load. Исключения могут быть неправильно перехвачены, и некоторые из них могут появиться в процессе работы. используйте нажатие кнопки.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 27.07.2014


Ответы (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. Не вызывать его из загрузки формы, отладка будет слишком сложной. Добавьте кнопку и вызовите Main из события click.

№ 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), а не long (Int64). Похоже, вы скопировали код из источника VB6, и он не обновляется должным образом (для этого нигде не нужно Long).

Для кодирования текста вы, вероятно, захотите этого:

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

а не Convert.ToByte, указанный выше. Как я уже сказал, я в основном стремился заставить его работать в той или иной форме, а не сертифицировать алгоритм.

person Ňɏssa Pøngjǣrdenlarp    schedule 27.07.2014
comment
Я бы использовал Return value, а не FunctionName = value. И некоторые комментарии в оригинале кажутся вводящими в заблуждение, например. '// Right shift an Unsigned Long 8 bits похоже, что должно быть ' Right shift by 8 bits and truncate. Хорошо, что код в Form_Load сложно отлаживать. Ваше исправление lIndex дает тот же результат, что и код OP. - person Andrew Morton; 27.07.2014
comment
@AndrewMorton да, старый стиль Returns и комментарии являются другими индикаторами того, что источником является преобразованный старый код VB6; также слишком много используется Long (Int64) для вычисления CRC32 в NET. Я вообще не возился с его алгоритмом, чтобы все не развалилось, просто исправил Option Strict проблемы и запустил его. Однако, глядя на материал CRC сейчас. - person Ňɏssa Pøngjǣrdenlarp; 27.07.2014
comment
System.Text.UTF8Encoding.UTF8.GetBytes — общедоступная общая функция.. и я предпочитаю FunctionName = value.. конечно, с логическими возвращаемыми функциями - person Brett Caswell; 27.07.2014
comment
comment
Да.. я имею в виду, что System.Text.Encoding.UTF8 является общедоступным общим свойством только для чтения. System.Text.Encoding.UTF8.GetBytes(s) или System.Text.UTF8Encoding.UTF8.GetBytes(s) будет достаточно - person Brett Caswell; 28.07.2014
comment
Большое спасибо, ребята. Я прошу прощения за то, что вернулся к вам так поздно, так как я был очень болен в последнее время. - person Jamy codes; 06.08.2014