PDA

View Full Version : CRC-16 calculaion with qChecksum



Tadas
29th May 2011, 17:43
I need to calculate crc-16 for this string:
0A0105000000102347455420444154414F524445520D0A01
Then answer should be: F65B(hex)
I can get this answer using online calculator http://www.zorc.breitbandkatze.de/crc.html
just click button crc-16 and paste line below and click compute
%0A%01%05%00%00%00%10%23%47%45%54%20%44%41%54%41%4 F%52%44%45%52%0D%0A%01
this will give the correct answer F65B, but I want to integrate it in to my qt code.

I was hoping to calculate CRC using qChecksum function.

QByteArray source = QString("0A0105000000102347455420444154414F524445520D0A01").toUtf8();
quint16 crc1 = qChecksum(source.data(), source.length());
qDebug() <<"crc1" <<crc1;
but answer is crc1 18940 (dec), 49FC (hex) , so it is wrong

This page also has a link to C code, but it is hard for me to understand it, i'm new with bytes and bits. http://www.zorc.breitbandkatze.de/crctester.c
Maybe someone could show me, how to do this calculation with qChecksum (if it is possible) or give any other hints.

SixDegrees
29th May 2011, 17:51
Read up on CRC algorithms (http://en.wikipedia.org/wiki/Cyclic_redundancy_check); there are 13 conflicting definitions of CRC-16, according to the article. You will first have to determine which is used by Qt, then find an independent source for comparison that uses the same variant.

Note that Qt seems to use CRC-16-CCITT.

ChrisW67
30th May 2011, 01:28
I need to calculate crc-16 for this string:
0A0105000000102347455420444154414F524445520D0A01
Then answer should be: F65B(hex)
I can get this answer using online calculator http://www.zorc.breitbandkatze.de/crc.html
just click button crc-16 and paste line below and click compute
%0A%01%05%00%00%00%10%23%47%45%54%20%44%41%54%41%4 F%52%44%45%52%0D%0A%01
this will give the correct answer F65B, but I want to integrate it in to my qt code.


There are numerous sites with CRC code in C that you can use if the Qt CCITT variant is not to your liking.

Regardless of which of the 16-bit CRC variant you use, it would certainly help if you fed the online CRC calculator and the Qt function the same input. Your code snippet feeds the Qt function a 48 byte string of characters, which is what your first sentence says you want to do. It seems obvious from your percent-encoded input to the online calculator that what you intended to do was send 24 bytes, the result of interpreting the original string as a hexadecimal representation of the bytes. Even using the same function this leads to different results:


char *chars = "0A0105000000102347455420444154414F524445520D0A01";
QByteArray bytes = QByteArray::fromHex(chars);
quint16 crcChars = qChecksum(chars, strlen(chars));
quint16 crcBytes = qChecksum(bytes.data(), bytes.length());
qDebug() << strlen(chars) << "chars"
<< hex << crcChars << "hex"
<< dec << crcChars << "decimal";
qDebug() << bytes.length() << "bytes"
<< hex << crcBytes << "hex"
<< dec << crcBytes << "decimal";



48 chars 49fc hex 18940 decimal
24 bytes 55ae hex 21934 decimal


What I find interesting is that Qt's answers doesn't seem to match other implementations of the same CCITT CRC-16: 0x52A6 (string) and 0xD2C2 (binary).