# Thread: CRC-16 calculation

1. ## CRC-16 calculation

Hello,
This is my first post - hopefully a correct forum

I am trying to figure out how to calculate CRC16 based on the following information. The device I am working with sends the following hex values:
Code:
`00,00,00,00,00,00,00,39,0C,01,08,00,00,00,31,10,A1,2B,26,00,C3,FA,0A,2A,DE,12,F8,1C,5F,50,9F,CB,14,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,54,65,73,74,00,4C,10,03,01,00,00,1F,E2,1F`
According to the very limited documentation the last 4 bytes (00,1F,E2,1F) are a CRC-16 value. For the past 2 days I was trying to calculate that value. I am assuming this CRC value is a for all of the bytes from 0 to n-4.

I need to be able to send the ACK to the device and that requires also a CRC to be attached in the last 4 bytes.

The manual asks to use the following code which I think is in C...
Code:
```        public static int getCrc16(byte[] buffer) {
return getCrc16(buffer, 0, buffer.length,  0xA001, 0);
}
public synchronized static int getCrc16(byte[] buffer, int offset, int bufLen, int polynom, int preset) {
preset &= 0xFFFF;
polynom &= 0xFFFF;
int crc = preset;
for (int i = 0; i < bufLen; i++) {
int data = buffer[i + offset] & 0xFF;
crc ^= data;
for (int j = 0; j < 8; j++) {
if ((crc & 0x0001) != 0) {
crc = (crc >> 1) ^ polynom;
} else {
crc = crc >> 1;
}
} }
return crc & 0xFFFF;
}```
Which I unfortunately cannot convert successfully to vb.net...
Any pointers to where I can find a good resource for CRC calculation would be appreciated.
Thanks!!

2. ## Re: CRC-16 calculation

Is that C function provided for the device is question in its documentation or did you find that separately on the internet ? If you found it separately, it may not work as I've seen here that CRC algorithms have slight variations. I don't want to spend the time to convert it and its not the variation the device expects to be used.

3. ## Re: CRC-16 calculation

Originally Posted by Niya
Is that C function provided for the device is question in its documentation or did you find that separately on the internet ? If you found it separately, it may not work as I've seen here that CRC algorithms have slight variations. I don't want to spend the time to convert it and its not the variation the device expects to be used.
Hello,
Yes. This sample is in the documentation attached to the device. So it should work if converted correctly. Thanks!

Anyone?

5. ## Re: CRC-16 calculation

Here is the conversion that I have published in my book. Give it a try (I think it is equivalent to the one that you want, though CRCs can get tricky):

Code:
```'Copyright Richard L. Grier, 2009
Public Class CRC
Public Function CRC(ByVal Data() As Byte) As Array
'#define POLY 0xA001
'unsigned int crc16( unsigned char *p, unsigned char n )
'{
'    unsigned char  i;
'    unsigned short crc = 0xFFFF;
'    while (n--)
'    {
'        crc ^= *p++;
'        for (i = 8; i != 0; i--)
'        {
'                If (crc & 1) Then
'                crc = (crc >> 1) ^ POLY;
'                Else
'                crc >>= 1;
'        }
'    }
'    return (crc);
'}
Dim CSRet(1) As Byte
Dim CS As UShort = &HFFFF
Dim Poly As UShort = &HA001
For I As Byte = 0 To Data.Length - 1
CS = CS Xor Data(I)
For K As Byte = 0 To 7
If CS And 1 Then
CS = (CS >> 1) Xor Poly
Else
CS >>= 1
End If
Next
Next
CSRet(0) = CByte(CS \ &HFF)
CSRet(1) = CByte(CS And &HFF)
Debug.Print(CS.ToString("X2"))
Return CSRet
End Function
End Class```
Dick

6. ## Re: CRC-16 calculation

That looks wrong. That function is returning the type Array. It would be better to return a Byte() or best, a Short.

7. ## Re: CRC-16 calculation

It returns an array of type Byte (which is OK, I think). If you want, you can modifiy the code -- that is fairly simple.

Dick

8. ## Re: CRC-16 calculation

Hello,
Can someone verify where I am making a mistake? I tried to convert the C code from the original post in this thread...
Code:
```    Public Function CRCcalc(ByVal incomingList As List(Of Byte))
Dim Preset As Integer = &HFFFF
Dim Polynom As Integer = &HFFFF
Dim CRC As Integer = Preset
For i = 0 To incomingList.Count - 1
Dim data As Integer = incomingList.Item(i) And &HFF
CRC ^= data
For j = 0 To 7
If (data And 1) <> 0 Then
CRC = (CRC >> 1) ^ Polynom
Else
CRC = CRC >> 1
End If
Next
Next
Return CRC And &HFFFF
End Function```
Any help appreciated!
Thanks!

Below is the original C code:
Code:
```        public static int getCrc16(byte[] buffer) {
return getCrc16(buffer, 0, buffer.length,  0xA001, 0);
}
public synchronized static int getCrc16(byte[] buffer, int offset, int bufLen, int polynom, int preset) {
preset &= 0xFFFF;
polynom &= 0xFFFF;
int crc = preset;
for (int i = 0; i < bufLen; i++) {
int data = buffer[i + offset] & 0xFF;
crc ^= data;
for (int j = 0; j < 8; j++) {
if ((crc & 0x0001) != 0) {
crc = (crc >> 1) ^ polynom;
} else {
crc = crc >> 1;
}
} }
return crc & 0xFFFF;
}```

9. ## Re: CRC-16 calculation

Are you sure that:

in C: polynom &= 0xFFFF;

in VB: Dim Polynom As Integer = &HFFFF

is equal?

10. ## Re: CRC-16 calculation

c++ Code:
`polynom &= 0xFFFF`
Should be:-
vbnet Code:
`Dim Polynom As Integer = Polynom And &hFFFF`

11. ## Re: CRC-16 calculation

Originally Posted by Niya
c++ Code:
`polynom &= 0xFFFF`
Should be:-
vbnet Code:
`Dim Polynom As Integer = Polynom And &hFFFF`
Right!

@marcellus
In your code no poly is passed into the function. It is just set to hffff which is no valid poly.

12. ## Re: CRC-16 calculation

Originally Posted by Niya
c++ Code:
`polynom &= 0xFFFF`
Should be:-
vbnet Code:
`Dim Polynom As Integer = Polynom And &hFFFF`
Thanks!
I don't know what I was thinking... below is the revised code.

Code:
```    Public Function CRCcalc(ByVal incomingList As List(Of Byte), ByVal preset As Integer, ByVal polynom As Integer)
preset &= &HFFFF
polynom &= &HFFFF
Dim CRC As Integer = Preset
For i = 0 To incomingList.Count - 1
Dim data As Integer = incomingList.Item(i) And &HFF
CRC ^= data
For j = 0 To 7
If (CRC And 1) <> 0 Then
CRC = (CRC >> 1) ^ polynom
Else
CRC = CRC >> 1
End If
Next
Next
Return CRC And &HFFFF
End Function```

13. ## Re: CRC-16 calculation

Originally Posted by marcellus
Thanks!
I don't know what I was thinking... below is the revised code.

Code:
```    Public Function CRCcalc(ByVal incomingList As List(Of Byte), ByVal preset As Integer, ByVal polynom As Integer)
preset &= &HFFFF
polynom &= &HFFFF
Dim CRC As Integer = Preset
For i = 0 To incomingList.Count - 1
Dim data As Integer = incomingList.Item(i) And &HFF
CRC ^= data
For j = 0 To 7
If (CRC And 1) <> 0 Then
CRC = (CRC >> 1) ^ polynom
Else
CRC = CRC >> 1
End If
Next
Next
Return CRC And &HFFFF
End Function```

Thanks, for help me.

Have this code for calculation of CRC 16 in C language, I need convert to vb.

function crc16str(str) {

return crc16(str);
}

function crc16(data) {
/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
const crctab16 = new Uint16Array([
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
]);
var len = data.length;
var buffer = 0;
var crc;
while (len--) {

crc = ((crc >>> 8) ^ (crctab16[(crc ^ (data[buffer++])) & 0xff]));

}
return crc;
// return [(crc >>> 8 & 0xff), (crc & 0xff)];
}

14. ## Re: CRC-16 calculation

You should probably make a new thread for this instead of resurrecting this 9 year old thread.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

Click Here to Expand Forum to Full Width