Thursday, September 26, 2013

CRC-CCITT Kermit 16 C++ Qt Implementation

CRC-CCITT Kermit 16 C++

Once I was needed to find CRC-CCITT Kermit 16 algo realization in C++. So here I found source code in Delphi and converted it to the C/C++ code (also for Qt).

Hope, that it will help you, guys.

C++11x and Qt


#include <QtCore>

quint16 makeCrc16Kermit(const QByteArray &data)
{
    quint16     valuehex = 0;
    quint16     CRC = 0;
    int         size = data.size();
    CRC = 0;

    for(int i=0; i<size; ++i) {
        valuehex = ((static_cast<quint8>(data[i]) ^ CRC) & 0x0fu) * 0x1081;
        CRC >>= 4;
        CRC ^= valuehex;
        valuehex = ((static_cast<quint8>(data[i]) >> 4) ^ (CRC & 0x00ffu)) & 0x0fu;
        CRC >>= 4;
        CRC ^= (valuehex * 0x1081u);
    }
    quint16 ret = ( (CRC & 0x00ffu) << 8) | ((CRC & 0xff00u) >> 8);
    return ret;
}

C++11x and Qt with pointers


quint16 makeCrc16Kermit(const QByteArray &data)
{
    quint16         valuehex = 0;
    quint16         CRC = 0;
    int             size = data.size();
    const quint8    *pData  = reinterpret_cast<const quint8*>(data.constData());

    CRC = 0;
    for(int i=0; i<size; ++i) {
        valuehex = ((*pData ^ CRC) & 0x0fu) * 0x1081;
        CRC >>= 4;
        CRC ^= valuehex;
        valuehex = ( (*pData >> 4) ^ (CRC & 0x00ffu) ) & 0x0fu;
        CRC >>= 4;
        CRC ^= (valuehex * 0x1081u);

        ++pData;
    }
    quint16 ret = ( (CRC & 0x00ffu) << 8) | ((CRC & 0xff00u) >> 8);
    return ret;
}

Any C compiler

Warning! Please, note that unsigned short int must have 2 bytes size!

unsigned short int makeCrc16Kermit(const void *data, const int size)
{
    unsigned short int  valuehex = 0x00;
    unsigned short int  CRC = 0x00;
    const char          *pData = (const char*)(data);

    CRC = 0;
    for(int i=0; i<size; ++i) {
        valuehex = ((*pData ^ CRC) & 0x0fu) * 0x1081;
        CRC >>= 4;
        CRC ^= valuehex;
        valuehex = ((*pData >> 4) ^ (CRC & 0x00ffu)) & 0x0fu;
        CRC >>= 4;
        CRC ^= (valuehex * 0x1081u);

        ++pData;
    }

    return ( (CRC & 0x00ffu) << 8) | ((CRC & 0xff00u) >> 8);
}




2 comments:

  1. hello,
    could you please explain why do you use 0x1081u,
    instead of 0x1021 as crccalc.com ?

    ReplyDelete
    Replies
    1. Hello,

      I don't remember much details, sorry. It was a long time ago.

      I'm pretty sure that I was working on communication with some hardware and probably matched configuration in hardware firmware.

      Hope it make any sense.

      Thank you.

      Delete