example for VB.NET to calculate CRC16 of an string or Byte Array - vb.net

With reference to this link
Calculate CRC32 of an String or Byte Array
I modified the code in order to calculate the CRC16 instead of CRC32, however I am getting wrong result, can some one point me where is the mistake?
Private Sub Main()
Crc16.ComputeChecksum(Encoding.UTF8.GetBytes("Some string"))
End Sub
Public Class CRC16
Shared table As UShort()
Shared Sub New()
Dim poly As UShort = &HA001US 'calculates CRC-16 using A001 polynomial (modbus)
table = New UShort(255) {}
Dim temp As UShort = 0
For i As UShort = 0 To table.Length - 1
temp = i
For j As Integer = 8 To 1 Step -1
If (temp And 1) = 1 Then
temp = CUShort((temp >> 1) Xor poly)
Else
temp >>= 1
End If
Next
table(i) = temp
Next
End Sub
Public Shared Function ComputeChecksum(ByVal bytes As Byte()) As UShort
Dim crc As UShort = &H0US ' The calculation start with 0x00
For i As Integer = 0 To bytes.Length - 1
Dim index As Byte = CByte(((crc) And &HFF) Xor bytes(i))
crc = CUShort((crc >> 8) Xor table(index))
Next
Return Not crc
End Function
End Class

Try this, it's working VB6 code for Instrument control. (sCommand is a temp string which contains all Bytes, Result is added to sCommand, Modbus is using LSB first, TextToString and StringToAscii are functions to convert a readable string "FF EE" into ASCII and back, thus they are not of interest here.):
Private Sub cmdCRC16_Click()
Dim sCommand As String
Dim x As Long
Dim y As Long
Dim lCRC As Long
sCommand = TextToString(txtASCII)
'Initial value
lCRC = 65535 '(&HFFFF results in Integer -1)
For x = 1 To Len(sCommand)
lCRC = lCRC Xor Asc(Mid(sCommand, x, 1))
For y = 1 To 8
If (lCRC Mod 2) > 0 Then
lCRC = (lCRC And 65534) / 2
lCRC = lCRC Xor 40961 '(&HA001 results in whatever negative integer)
Else
lCRC = (lCRC And 65534) / 2
End If
Next y
Next x
'Add CRC with LSB first
sCommand = sCommand + Chr(lCRC And 255)
sCommand = sCommand + Chr((lCRC And 65280) / 256)
txtASCII = StringToASCII(sCommand)
End Sub

I just came accross the same issue. Simple solution is to omit negation at the end, so just change your "Return Not crc" to "Return crc" and you be fine.
There are various variants of CRC-16, where "CRC-16" normally refers to the IBM variant, also called "ARC". It uses an XorOut value of zero. See Catalogue of parametrised CRC algorithms with 16 bits.

Related

CRC64 calculation in VB

I'm using the code I found [here][1] tot calculate a CRC32 checksum.
I would also like to calculate a CRC64 checksum. But I can't figure out how to do this.
Any help would be appreciated!
Below the code from "Magnus" I'm using for CRC32.
Private Sub Main()
Crc32.ComputeChecksum(Encoding.UTF8.GetBytes("Some string")).Dump()
End Sub
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
Thanks to Mark Adler I got the code working!
The code bellow produces the following result:
CRC64: 995DC9BBDF1939FA
Private Sub Main()
Try
MessageBox.Show("CRC64: " & UCase(Hex(CRC64.ComputeChecksum(System.Text.Encoding.UTF8.GetBytes("123456789")))))
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
Public Class CRC64
Shared table As ULong()
Shared Sub New()
Dim poly As ULong = &Hc96c5795d7870f42UL
table = New ULong(255) {}
Dim temp As ULong = 0
For i As ULong = 0 To table.Length - 1
temp = i
For j As Integer = 8 To 1 Step -1
If (temp And 1UL) = 1 Then
temp = CULng((temp >> 1) Xor poly)
Else
temp >>= 1
End If
Next
table(i) = temp
Next
End Sub
Public Shared Function ComputeChecksum(bytes As Byte()) As ULong
Dim crc As ULong = &HffffffffffffffffUL
Dim i As Integer
For i = 0 To bytes.Length - 1
Dim index As Byte = CByte(((crc) And &HffUL) Xor bytes(i))
crc = CULng((crc >> 8) Xor table(index))
Next i
Return Not crc
End Function
End Class
[1]: https://stackoverflow.com/questions/15553697/calculate-crc32-of-an-string-or-byte-array
First you need to find a CRC-64 description to implement. You don't just want to pick a random polynomial. This one, CRC-64/XZ, from here would be easiest to convert your implementation to:
width=64 poly=0x42f0e1eba9ea3693 init=0xffffffffffffffff refin=true refout=true xorout=0xffffffffffffffff check=0x995dc9bbdf1939fa residue=0x49958c9abd7d353f name="CRC-64/XZ"
You need to take that poly and reverse the 64 bits to use as your poly. You need to use ULong instead of UInteger types in the calculation to hold 64 bits. You need to have twice as many fs for that all-ones value in 64 bits. Then you should be good to go.
Check your code by replacing "Some string" with "123456789" and see if you get the check= value in the CRC definition above.
Private Sub Main()
Try
MessageBox.Show("CRC64: " & UCase(Hex(CRC64.ComputeChecksum(System.Text.Encoding.UTF8.GetBytes("123456789")))))
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
Public Class CRC64
Shared table As ULong()
Shared Sub New()
Dim poly As ULong = &Hc96c5795d7870f42UL
table = New ULong(255) {}
Dim temp As ULong = 0
For i As ULong = 0 To table.Length - 1
temp = i
For j As Integer = 8 To 1 Step -1
If (temp And 1UL) = 1 Then
temp = CULng((temp >> 1) Xor poly)
Else
temp >>= 1
End If
Next
table(i) = temp
Next
End Sub
Public Shared Function ComputeChecksum(bytes As Byte()) As ULong
Dim crc As ULong = &HffffffffffffffffUL
Dim i As Integer
For i = 0 To bytes.Length - 1
Dim index As Byte = CByte(((crc) And &HffUL) Xor bytes(i))
crc = CULng((crc >> 8) Xor table(index))
Next i
Return Not crc
End Function
End Class

crc16 ccitt from a byte array

I need some help with creating checksum for tcp packet from an array
of byte.
This is code is working as I've tested it with
string.
Problem is I've to pass an array of byte to this
function.
At this moment I've created it simple by using hard
embedded time serial number otherwise it is very long code to login
to a device.
Value of this is b1:68:de:3a:15:cd:5b:07 checked with wireshark and CRC should be E2B6 checked with online crc this
Now, coming to main point I just can't call this method as this method is expecting some string values and I've to pass hex values. How I can do that.
Private Sub ConnectTCP_Click(sender As Object, e As EventArgs) Handles ConnectTCP.Click
Dim Serial As UInt32 = "123456789"
Dim time As UInt32 = "987654321"
Dim buffer2() As Byte = BitConverter.GetBytes(time)
Dim buffer3() As Byte = BitConverter.GetBytes(Serial)
Dim array4(buffer2.Length + buffer3.Length - 1) As Byte
Array.Copy(buffer2, array4, buffer2.Length)
Array.Copy(buffer3, 0, array4, buffer2.Length, buffer3.Length)
getCRC16(array4) 'What I need to do here
end sub
"CRC16 CCITT function""
Public Function getCRC16(ByVal strInput As String)
Dim lngCheck As Long
Dim Power(7) As Integer
Dim I As Integer
Dim J As Integer
Dim Poly As Long
Dim CRC As Long
Dim TestBit As Boolean
Dim TestBit1 As Boolean
Dim TestBit2 As Boolean
Poly = &H1021
CRC = &HFFFF
For J = 0 To 7
Power(J) = 2 ^ J
Next J
For I = 1 To Len(strInput)
lngCheck = Asc(Mid$(strInput, I, 1))
For J = 7 To 0 Step -1
If (CRC And 32768) = 32768 Then
TestBit1 = True
Else
TestBit1 = False
End If
If (lngCheck And Power(J)) = Power(J) Then
TestBit2 = True
Else
TestBit2 = False
End If
TestBit = TestBit1 Xor TestBit2
CRC = (CRC And 32767) * 2
If TestBit = True Then
CRC = CRC Xor Poly
End If
Next J
Next I
Dim tmp As String
tmp = Hex(CRC)
CRCTCP.Text = tmp
getCRC16 = tmp
End Function
Finally, Found It.
Public Class CRC16CCITT
Public Enum InitialCRCValue
Zeroes = 0
NonZero1 = &HFFFF
NonZero2 = &H1D0F
'NonZero3 = &H0
End Enum
Private Const poly As UShort = &H1021 'polynomial
Dim table(255) As UShort
Dim intValue As UShort = 0
Public Function ComputeCheckSum(ByVal bytes As Byte()) As UShort
Dim crc As UShort = Me.intValue
'Dim x As String
For i As Integer = 0 To bytes.Length - 1
crc = CUShort(((crc << 8) Xor table(((crc >> 8) Xor (&HFF And bytes(i))))))
'crc = (crc << 8) ^ (x << 15) ^ (x << 2) ^ x
Next
Return crc
End Function
Public Function ComputeCheckSumBytes(ByVal bytes As Byte()) As Byte()
Dim crc As UShort = ComputeCheckSum(bytes)
Return BitConverter.GetBytes(crc)
End Function
Public Sub New(ByVal initialvalue As InitialCRCValue)
Me.intValue = CUShort(initialvalue)
Dim temp, a As UShort
For i As Integer = 0 To table.Length - 1
temp = 0
a = CUShort(i << 8)
For j As Integer = 0 To 7
If ((temp Xor a) And &H8000) <> 0 Then
temp = CUShort((temp << 1) Xor poly)
Else
temp <<= 1
End If
a <<= 1
Next
table(i) = temp
Next
End Sub
End Class

Calcule the CRC16 whit POLYNOMIAL 0x8408 and initial crc 0xFFFF

Hi I need get the CRC16 with polynomial 0x8408 and initial 0xFFFF, in this post I found a equal case
C# CRC-16-CCITT 0x8408 Polynomial. Help needed
but I am working in VB 2013 and I intend write the same code but in this language
Private Sub crc16calc_Click(sender As Object, e As EventArgs) Handles crc16calc.Click
Dim data As UShort = 0
Dim crc As UShort = &HFFFF
Dim pru() As Byte = {&H5, &H0, &H4, &HFB, &H4A, &H43}
For j As UInteger = 0 To pru.Length - 1
crc = CUShort(crc ^ pru(j))
For i As UInteger = 0 To 7
If ((crc & &H1) = 1) Then
crc = CUShort((crc >> 1) ^ &H8408)
Else
crc >>= 1
End If
Next
Next
crc = CUShort(Not crc)
data = crc
crc = CUShort((crc << 8) ^ (data >> 8 & &HFF))
MsgBox(crc)
End Sub
But when I execute this code get a overflow in crc = CUShort(crc ^ pru(j))
Can any help me.
Private Sub crc16calc_Click(sender As Object, e As EventArgs) Handles crc16calc.Click
Dim data As UShort
Dim PRESET_VALUE As UShort = &HFFFF
Dim POLYNOMIAL As UShort = &H8408
Dim pru() As Byte = {&H4, &H0, &H1, &HDB, &H4B} ' the two last bytes are the CRC16
Dim pru2() As Byte = {&H5, &H0, &H1, &HFB, &HF2, &H3D}
Dim ucX As Integer = pru.Length - 3
Dim uiCrcValue As UShort = PRESET_VALUE
For j As Integer = 0 To ucX
uiCrcValue = uiCrcValue Xor pru(j)
For i As Integer = 0 To 7
If (uiCrcValue And 1) Then
uiCrcValue = (uiCrcValue >> 1) Xor POLYNOMIAL
Else
uiCrcValue = uiCrcValue >> 1
End If
Next
Next
'MsgBox(uiCrcValue)
data = uiCrcValue
uiCrcValue = CUShort((uiCrcValue << 8) Xor ((data >> 8) And &HFF))
MsgBox(uiCrcValue)
End Sub
Thanks, the code is working
In C# the ^ operator is xor. In VB, the ^ operator is exponentiation.
Just change each ^ to Xor.

Decimal to binary for large number (>2253483438943167)

I have a VB.Net application that goes through a series of processes to decode a string, one problem with this is that I have found a function that converts from binary to decimal for any number, but I cannot find a function that will convert a supplied number (in string format) into a binary string. For reference, the binary to decimal conversion function is below:
Public Function baseconv(d As String)
Dim N As Long
Dim Res As Long
For N = Len(d) To 1 Step -1
Res = Res + ((2 ^ (Len(d) - N)) * CLng(Mid(d, N, 1)))
Next N
Return Str(Res)
End Function
What i would do if the number is less than 16*1e18 <-> can hold in a Uint64 :
1) store the number inside an unsigned 64 bits integer : num.
2) then just loop on each bit to test it :
mask = 1<<63
do
if ( num AND mask ) then ->> push("1")
else ->> push("0")
mask = mask >> 1
until mask = 0
(where push builds the output with a string concatenation, or, if performance matters, a StringBuilder, or it can be a stream,... )
what about this?
Module Module1
Sub Main()
Console.WriteLine(Convert.ToString(2253483438943167 * 5, 2))
Console.ReadKey()
End Sub
End Module
Try using the System.Numerics.BigInteger class like this:
Dim d As String
d = "2253483438943167"
Dim bi As BigInteger
bi = BigInteger.Parse(d)
Dim ba() As Byte
ba = bi.ToByteArray()
Dim s As String
Dim N As Long
Dim pad as Char
pad = "0"c
For N = Len(ba) To 1 Step -1
s = s + Convert.ToString(ba(N)).PadLeft(8, pad)
Next N
How about
Dim foo As BigInteger = Long.MaxValue
foo += Long.MaxValue
foo += 2
Dim s As New System.Text.StringBuilder
For Each b As Byte In foo.ToByteArray.Reverse
s.Append(Convert.ToString(b, 2).PadLeft(8, "0"c))
Next
Debug.WriteLine(s.ToString.TrimStart("0"c))
'10000000000000000000000000000000000000000000000000000000000000000

Calculate CRC32 of an String or Byte Array [duplicate]

This question already has answers here:
How do I calculate CRC32 of a string
(3 answers)
Closed 9 years ago.
Is there any function or example for VB.NET to calculate CRC32 of an string or Byte Array?
Use this:
Private Sub Main()
Crc32.ComputeChecksum(Encoding.UTF8.GetBytes("Some string")).Dump()
End Sub
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