CRC16 with CCIT checksum in VB.NET

Posted on 2010-11-20
Last Modified: 2012-05-10

I'm looking everywhere to find a working function to calculate the cheksum needed by a device we communicate through socket connexion in VB 2008. Documentation give the following:

A Cyclic Redundancy Check (CRC) detects errors and is positioned at the end of the packet. The 16-bit CRC is calculated on all bytes of the packet following the SOF. The CRC uses the CCITT polynomial (X16 + X12 + X5 + 1) with a seed or preload value of 0xBEEF. The bitwise inversion of the calculated value is appended to the end of the data section of the packet, with the LSB first.

 * This is the table used to by the table lookup method of generating CCITT CRC values.
 * The CCITT polynomial is x^16 + x^12 + x^5 + 1 reverse direction table - i.e. LSBit first
 static const uint16 crcTable[256] =
 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78

 * uint16 calcBlockCRC(size_t count, uint16 crc, void *buffer)
 * size_t count : Number of bytes in the buffer
 * uint16 crc : Preload value of the CRC
 * void *buffer : Buffer whose CRC is to be calculated
 * This routine is called to calculate the CCITT CRC value of a block of data.

 * CRC value.

 uint16 calcBlockCRC(size_t count, uint16 crc, void *buffer)
 const uint8 *pBuf = (const uint8*)buffer;

 while (count--)
 crc = (uint16)((crc >> 8) ^ crcTable[(uint8)(crc ^ *pBuf++)])
 return (crc ^ ((uint16)0xFFFF));

I try to send the following:
Dim msg(18) As Byte
        msg(0) = &H1
        msg(1) = &H4
        msg(2) = &H12
        msg(3) = &H1
        msg(4) = &H5
        msg(5) = &H61
        msg(6) = &H64
        msg(7) = &H6D
        msg(8) = &H69
        msg(9) = &H6E
        msg(10) = &H6
        msg(11) = &H63
        msg(12) = &H68
        msg(13) = &H61
        msg(14) = &H6E
        msg(15) = &H67
        msg(16) = &H65

checksum should be &H4E97 (as given by the device itself) and inserted in the array as:
        msg(17) = &H97
        msg(18) = &H4E

But every functions, classes or code sample I could find on the internet can't give me the required checksum.

Anyone can help me please?
thanks a lot for your time and help
Question by:Dominic34
  • 2

Author Comment

ID: 34180034
Forgot to mention the CRC is calculated without the first &H1

Accepted Solution

logic_chopper earned 500 total points
ID: 34219474
If I understand your question correctly, you're looking for a VB.NET implementation of the CRC code.  I have converted the C function to VB.NET and have attached the code below.  When you run it the crc variable will contain the value 4E97 as required.  If you have any further questions then let me know.
Public Class Form1

    Public Function CRCBlock(ByVal count As Integer, ByVal crc As Integer, ByRef buffer As Byte())

        Dim crcTable() As UShort =
&H0, &H1189, &H2312, &H329B, &H4624, &H57AD, &H6536, &H74BF,
&H8C48, &H9DC1, &HAF5A, &HBED3, &HCA6C, &HDBE5, &HE97E, &HF8F7,
&H1081, &H108, &H3393, &H221A, &H56A5, &H472C, &H75B7, &H643E,
&H9CC9, &H8D40, &HBFDB, &HAE52, &HDAED, &HCB64, &HF9FF, &HE876,
&H2102, &H308B, &H210, &H1399, &H6726, &H76AF, &H4434, &H55BD,
&HAD4A, &HBCC3, &H8E58, &H9FD1, &HEB6E, &HFAE7, &HC87C, &HD9F5,
&H3183, &H200A, &H1291, &H318, &H77A7, &H662E, &H54B5, &H453C,
&HBDCB, &HAC42, &H9ED9, &H8F50, &HFBEF, &HEA66, &HD8FD, &HC974,
&H4204, &H538D, &H6116, &H709F, &H420, &H15A9, &H2732, &H36BB,
&HCE4C, &HDFC5, &HED5E, &HFCD7, &H8868, &H99E1, &HAB7A, &HBAF3,
&H5285, &H430C, &H7197, &H601E, &H14A1, &H528, &H37B3, &H263A,
&HDECD, &HCF44, &HFDDF, &HEC56, &H98E9, &H8960, &HBBFB, &HAA72,
&H6306, &H728F, &H4014, &H519D, &H2522, &H34AB, &H630, &H17B9,
&HEF4E, &HFEC7, &HCC5C, &HDDD5, &HA96A, &HB8E3, &H8A78, &H9BF1,
&H7387, &H620E, &H5095, &H411C, &H35A3, &H242A, &H16B1, &H738,
&HFFCF, &HEE46, &HDCDD, &HCD54, &HB9EB, &HA862, &H9AF9, &H8B70,
&H8408, &H9581, &HA71A, &HB693, &HC22C, &HD3A5, &HE13E, &HF0B7,
&H840, &H19C9, &H2B52, &H3ADB, &H4E64, &H5FED, &H6D76, &H7CFF,
&H9489, &H8500, &HB79B, &HA612, &HD2AD, &HC324, &HF1BF, &HE036,
&H18C1, &H948, &H3BD3, &H2A5A, &H5EE5, &H4F6C, &H7DF7, &H6C7E,
&HA50A, &HB483, &H8618, &H9791, &HE32E, &HF2A7, &HC03C, &HD1B5,
&H2942, &H38CB, &HA50, &H1BD9, &H6F66, &H7EEF, &H4C74, &H5DFD,
&HB58B, &HA402, &H9699, &H8710, &HF3AF, &HE226, &HD0BD, &HC134,
&H39C3, &H284A, &H1AD1, &HB58, &H7FE7, &H6E6E, &H5CF5, &H4D7C,
&HC60C, &HD785, &HE51E, &HF497, &H8028, &H91A1, &HA33A, &HB2B3,
&H4A44, &H5BCD, &H6956, &H78DF, &HC60, &H1DE9, &H2F72, &H3EFB,
&HD68D, &HC704, &HF59F, &HE416, &H90A9, &H8120, &HB3BB, &HA232,
&H5AC5, &H4B4C, &H79D7, &H685E, &H1CE1, &HD68, &H3FF3, &H2E7A,
&HE70E, &HF687, &HC41C, &HD595, &HA12A, &HB0A3, &H8238, &H93B1,
&H6B46, &H7ACF, &H4854, &H59DD, &H2D62, &H3CEB, &HE70, &H1FF9,
&HF78F, &HE606, &HD49D, &HC514, &HB1AB, &HA022, &H92B9, &H8330,
&H7BC7, &H6A4E, &H58D5, &H495C, &H3DE3, &H2C6A, &H1EF1, &HF78

        Dim index As Integer = 0

        While (index < count)
            crc = (crc >> 8) Xor crcTable(CByte((crc Xor buffer(index)) And &HFF))
            index = index + 1
        End While

        CRCBlock = crc Xor &HFFFF

    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim msg() As Byte =
        {&H4, &H12, &H1, &H5, &H61, &H64, &H6D, &H69, &H6E, &H6, &H63, &H68, &H61, &H6E, &H67, &H65}

        Dim crc As UShort = CRCBlock(msg.Length, &HBEEF, msg)

    End Sub

End Class

Open in new window


Author Comment

ID: 34221644
this is exaclty that I was looking for.
thanks a lot

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Gridview selected row 9 47
start a process from a service 3 23
Help with converting xml file to excel using VB.NET 3 20 1 month apart 11 31
Entering a date in Microsoft Access can be tricky. A typo can cause month and day to be shuffled, entering the day only causes an error, as does entering, say, day 31 in June. This article shows how an inputmask supported by code can help the user a…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question