|
なちゃさん
C#のDLLを読み込む方法でうまくいったのですが 後学のためにVBコードに変換しても実行してみたいと考えています。
SharpDevelopを使うことで ほとんどエラーなく以下のようにVBコードに変換することができました。
Namespace Force_Crc32 Friend Class SafeProxy Private Const Poly As UInteger = &HEDB88320UI
Private Shared ReadOnly _table As UInteger() = New UInteger(16 * 256 - 1) {}
Shared Sub New() For i As UInteger = 0 To 255 Dim res As UInteger = i For t As Integer = 0 To 15 For k As Integer = 0 To 7 res = If((res And 1) = 1, Poly Xor (res >> 1), (res >> 1)) Next _table((t * 256) + i) = res Next Next End Sub
Public Function Append(ByVal crc As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger Dim crcLocal As UInteger = UInteger.MaxValue Xor crc
Dim table As UInteger() = _table While length >= 16 crcLocal = table((15 * 256) + ((crcLocal Xor input(offset)) And &HFF)) _ Xor table((14 * 256) + (((crcLocal >> 8) Xor input(offset + 1)) And &HFF)) _ Xor table((13 * 256) + (((crcLocal >> 16) Xor input(offset + 2)) And &HFF)) _ Xor table((12 * 256) + (((crcLocal >> 24) Xor input(offset + 3)) And &HFF)) _ Xor table((11 * 256) + input(offset + 4)) _ Xor table((10 * 256) + input(offset + 5)) _ Xor table((9 * 256) + input(offset + 6)) _ Xor table((8 * 256) + input(offset + 7)) _ Xor table((7 * 256) + input(offset + 8)) _ Xor table((6 * 256) + input(offset + 9)) _ Xor table((5 * 256) + input(offset + 10)) _ Xor table((4 * 256) + input(offset + 11)) _ Xor table((3 * 256) + input(offset + 12)) _ Xor table((2 * 256) + input(offset + 13)) _ Xor table((1 * 256) + input(offset + 14)) _ Xor table((0 * 256) + input(offset + 15)) offset += 16 length -= 16 End While
While System.Threading.Interlocked.Decrement(length) >= 0 crcLocal = table((crcLocal Xor input(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1))) And &HFF) Xor crcLocal >> 8 End While Return crcLocal Xor UInteger.MaxValue End Function End Class End Namespace
Imports System Imports System.Security.Cryptography
Namespace Force_Crc32 ''' <summary> ''' Implementation of CRC-32. ''' This class supports several convenient static methods returning the CRC as UInt32. ''' </summary> Public Class Crc32Algorithm Inherits HashAlgorithm Private _currentCrc As UInteger
''' <summary> ''' Initializes a new instance of the <see cref="Crc32Algorithm"/> class. ''' </summary> Public Sub New() #If Not NETCORE Then #End If HashSizeValue = 32 End Sub
''' <summary> ''' Computes CRC-32 from multiple buffers. ''' Call this method multiple times to chain multiple buffers. ''' </summary> ''' <param name="initial"> ''' Initial CRC value for the algorithm. It is zero for the first buffer. ''' Subsequent buffers should have their initial value set to CRC value returned by previous call to this method. ''' </param> ''' <param name="input">Input buffer with data to be checksummed.</param> ''' <param name="offset">Offset of the input data within the buffer.</param> ''' <param name="length">Length of the input data in the buffer.</param> ''' <returns>Accumulated CRC-32 of all buffers processed so far.</returns> Public Shared Function Append(ByVal initial As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger If input Is Nothing Then Throw New ArgumentNullException() End If If offset < 0 OrElse length < 0 OrElse offset + length > input.Length Then Throw New ArgumentOutOfRangeException("Selected range is outside the bounds of the input array") End If Return AppendInternal(initial, input, offset, length) End Function
''' <summary> ''' Computes CRC-3C from multiple buffers. ''' Call this method multiple times to chain multiple buffers. ''' </summary> ''' <param name="initial"> ''' Initial CRC value for the algorithm. It is zero for the first buffer. ''' Subsequent buffers should have their initial value set to CRC value returned by previous call to this method. ''' </param> ''' <param name="input">Input buffer containing data to be checksummed.</param> ''' <returns>Accumulated CRC-32 of all buffers processed so far.</returns> Public Shared Function Append(ByVal initial As UInteger, ByVal input As Byte()) As UInteger If input Is Nothing Then Throw New ArgumentNullException() End If Return AppendInternal(initial, input, 0, input.Length) End Function
''' <summary> ''' Computes CRC-32 from input buffer. ''' </summary> ''' <param name="input">Input buffer with data to be checksummed.</param> ''' <param name="offset">Offset of the input data within the buffer.</param> ''' <param name="length">Length of the input data in the buffer.</param> ''' <returns>CRC-32 of the data in the buffer.</returns> Public Shared Function Compute(ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger Return Append(0, input, offset, length) End Function
''' <summary> ''' Computes CRC-32 from input buffer. ''' </summary> ''' <param name="input">Input buffer containing data to be checksummed.</param> ''' <returns>CRC-32 of the buffer.</returns> Public Shared Function Compute(ByVal input As Byte()) As UInteger Return Append(0, input) End Function
''' <summary> ''' Resets internal state of the algorithm. Used internally. ''' </summary> Public Overrides Sub Initialize() _currentCrc = 0 End Sub
''' <summary> ''' Appends CRC-32 from given buffer ''' </summary> Protected Overrides Sub HashCore(ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) _currentCrc = AppendInternal(_currentCrc, input, offset, length) End Sub
''' <summary> ''' Computes CRC-32 from <see cref="HashCore"/> ''' </summary> Protected Overrides Function HashFinal() As Byte() ' Crc32 by dariogriffo uses big endian, so, we need to be compatible and return big endian too Return New Byte() {CByte(_currentCrc >> 24), CByte(_currentCrc >> 16), CByte(_currentCrc >> 8), CByte(_currentCrc)} End Function
Private Shared ReadOnly _proxy As New SafeProxy()
Private Shared Function AppendInternal(ByVal initial As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger If length > 0 Then Return _proxy.Append(initial, input, offset, length) Else Return initial End If End Function End Class End Namespace
しかし、実行しても、 エラーは出ないのですが、0しか返しません。
なにが原因でしょうか?
ちなみにSharpDevelopでコードを変換後に
Return New () {CByte(_currentCrc >> 24), CByte(_currentCrc >> 16), CByte(_currentCrc >> 8), CByte(_currentCrc)}
res = If((res And 1) is 1, Poly Xor (res >> 1), (res >> 1))
でエラーが出たので それぞれ以下のように変更しました
Return New Byte() {CByte(_currentCrc >> 24), CByte(_currentCrc >> 16), CByte(_currentCrc >> 8), CByte(_currentCrc)}
res = If((res And 1) = 1, Poly Xor (res >> 1), (res >> 1))
|