Main Page | Projects IndexGallery Index | Data & Infomation

 

Calculating CRC16 in VB.Net

Overview

 

The following process describes the steps necessary in order to calculate the CRC value for a string of bytes. A tested program is also provided in the links at the bottom of the page, this was built in VB2017.

In order to process a packet of bytes we must follow a fixed sequence, initially the CRC should be preloaded with HFFFF and this should then be XORed with a packet byte. The result of this is then right shifted 8 times. On each rotation if a carry results the CRC will need to be further XORed with the polynomial HA001. As each byte is considered the CRC result from the last calculation is fed into the beginning of the next.

Once all of the bytes have been considered the resulting number is byte swapped and can be compared to the CRC appended to the end of the received message.

 

Flow Diagram

 

This is probably better explained with a flow diagram.

 
 

Worked Example

 

A practical worked example was made using the process above :

 

 

 

Using above as a guide, a program was then developed that produced a visual printout of the calculation as it is made. A CRC16 function is also contained within the program. The listing for just the CRC16 function is given below.

Function crc16(message As String) As Integer
    'declare variables
    Dim message_lenght As Integer
    Dim xor_loops As Byte
    Dim message_byte_snip As String
    Dim message_byte As UInt16
    Dim crc As UInt16 = &HFFFF
    Dim poly As UInt16 = &HA001
    Dim rotate_carry As Boolean
    Dim mbyte As Byte
    Dim upper_crc As UInt16
    Dim lower_crc As UInt16

    'find string lenght
    message_lenght = Len(message) / 2
    'loop through message
    For mbyte = 1 To message_lenght * 2 Step 2

       'get message byte and convert to decimal
       message_byte_snip = Mid(message, mbyte, 2)
       message_byte = Convert.ToInt32(message_byte_snip, 16)

       'xor crc with message byte
       crc = crc Xor message_byte

       'xor 8 times
       For xor_loops = 1 To 8
           'check for carry
           If crc And 1 Then rotate_carry = True Else rotate_carry = False
           If rotate_carry = True Then crc = crc - 1
           crc = crc / 2
           'xor with poly if carry
           If rotate_carry Then crc = crc Xor poly
       Next xor_loops
    Next mbyte
    'byte swap
    upper_crc = (crc And &HFF00) / 256
    lower_crc = crc And &HFF
    'return crc
    crc16 = lower_crc *256 +  upper_crc
End Function

The attached program (see link below) performs the CRC calculation and gives a breakdown of the process, the program was given the string 1103006B0003 and the printout below was produced.

msg byte  11
xor           FFEE
rotate 1   7FF7   Carry:False
rotate 2   9FFA   Carry:True
rotate 3   4FFD   Carry:False
rotate 4   87FF   Carry:True
rotate 5   E3FE   Carry:True
rotate 6   71FF   Carry:False
rotate 7   98FE   Carry:True
rotate 8   4C7F   Carry:False
msg byte  03
xor           4C7C
rotate 1   263E   Carry:False
rotate 2   131F   Carry:False
rotate 3   A98E   Carry:True
rotate 4   54C7   Carry:False
rotate 5   8A62   Carry:True
rotate 6   4531   Carry:False
rotate 7   8299   Carry:True
rotate 8   E14D   Carry:True
msg byte  00
xor           E14D
rotate 1   D0A7   Carry:True
rotate 2   C852   Carry:True
rotate 3   6429   Carry:False
rotate 4   9215   Carry:True
rotate 5   E90B   Carry:True
rotate 6   D484   Carry:True
rotate 7   6A42   Carry:False
rotate 8   3521   Carry:False
msg byte  6B
xor           354A
rotate 1   1AA5   Carry:False
rotate 2   AD53   Carry:True
rotate 3   F6A8   Carry:True
rotate 4   7B54   Carry:False
rotate 5   3DAA   Carry:False
rotate 6   1ED5   Carry:False
rotate 7   AF6B   Carry:True
rotate 8   F7B4   Carry:True
msg byte  00
xor           F7B4
rotate 1   7BDA   Carry:False
rotate 2   3DED   Carry:False
rotate 3   BEF7   Carry:True
rotate 4   FF7A   Carry:True
rotate 5   7FBD   Carry:False
rotate 6   9FDF   Carry:True
rotate 7   EFEE   Carry:True
rotate 8   77F7   Carry:False
msg byte  03
xor           77F4
rotate 1   3BFA   Carry:False
rotate 2   1DFD   Carry:False
rotate 3   AEFF   Carry:True
rotate 4   F77E   Carry:True
rotate 5   7BBF   Carry:False
rotate 6   9DDE   Carry:True
rotate 7   4EEF   Carry:False
rotate 8   8776   Carry:True

 

Links:

 

VB Example with string input and integer ouput Demo_1

VB Example with byte array input and integer ouput Demo_2