# How to compute CRC 16 in Python and C The test program shown here demonstrates how to compute CRC-16 DNP in Python using two different packages, PyCRC and crcmod. The latter not only exports a lot more of precooked CRC polynomials but is even able to generate standard C code that could be embedded into a microcontroller talking to the master (usually implemented in a Linux machine). The CRC polynomial is a 16 bit in order to save bandwidth on the serial line.Moreover, both the Python modules and the generated C code are able to cope with odd-number of bytes, contributing to a more efficient message format. <pre class="prettyprint"> # install crcmod module sudo pip install crcmod # start Python python import crcmod # select CRC-16-DNP crc16 = crcmod.mkCrcFun(0x13D65, 0xFFFF, True, 0xFFFF) # test hex(crc16('123456789')) '0xea82' # generate the code crc16_gen_code = crcmod.Crc(0x13D65, 0xFFFF, True, 0xFFFF) f = open('crc-16-dnp.h', 'w') crc16_gen_code.generateCode('crcr16dnp.h',f) exit </pre> /* * CRC-16 DNP test * * http://crcmod.sourceforge.net/crcmod.html * http://crcmod.sourceforge.net/crcmod.predefined.html#class-predefinedcrc * * crcmod * sudo pip install crcmod * python * import crcmod * * crc16 = crcmod.mkCrcFun(0x13D65, 0xFFFF, True, 0xFFFF) * hex(crc16('123456789')) * '0xea82' * * crc16_gen_code = crcmod.Crc(0x13D65, 0xFFFF, True, 0xFFFF) * f = open('crc-16-dnp.h', 'w') * crc16_gen_code.generateCode('crcr16dnp.h',f) * exit * * gcc test_crc16dnp.c -o test_crc16dnp && ./test_crc16dnp '123456789' * * http://www.sunshine2k.de/coding/javascript/crc/crc_js.html * * check with CRC16_DNP * * * PyCRC * * python * input = '123456789' * from PyCRC.CRC16DNP import CRC16DNP * print(hex(CRC16DNP().calculate(input))) * 0x82ea */ #include <stdio.h> #include <string.h> #include <stdint.h> #define UINT8 uint8_t #define UINT16 uint16_t #include "crc-16-dnp.h" int main (const int argc, char **argv) { if (argc > 1) { fprintf(stderr, "Input: [%s]\n", argv[1]); uint16_t crc = crcr16dnp(argv[1], strlen(argv[1]), 0xFFFF); printf ("%04x", crc); } else { fprintf(stderr, "Argument missing.\n"); } } // Automatically generated CRC function // polynomial: 0x13D65, bit reverse algorithm UINT16 crcr16dnp.h(UINT8 *data, int len, UINT16 crc) { static const UINT16 table[256] = { 0x0000U,0x365EU,0x6CBCU,0x5AE2U,0xD978U,0xEF26U,0xB5C4U,0x839AU, 0xFF89U,0xC9D7U,0x9335U,0xA56BU,0x26F1U,0x10AFU,0x4A4DU,0x7C13U, 0xB26BU,0x8435U,0xDED7U,0xE889U,0x6B13U,0x5D4DU,0x07AFU,0x31F1U, 0x4DE2U,0x7BBCU,0x215EU,0x1700U,0x949AU,0xA2C4U,0xF826U,0xCE78U, 0x29AFU,0x1FF1U,0x4513U,0x734DU,0xF0D7U,0xC689U,0x9C6BU,0xAA35U, 0xD626U,0xE078U,0xBA9AU,0x8CC4U,0x0F5EU,0x3900U,0x63E2U,0x55BCU, 0x9BC4U,0xAD9AU,0xF778U,0xC126U,0x42BCU,0x74E2U,0x2E00U,0x185EU, 0x644DU,0x5213U,0x08F1U,0x3EAFU,0xBD35U,0x8B6BU,0xD189U,0xE7D7U, 0x535EU,0x6500U,0x3FE2U,0x09BCU,0x8A26U,0xBC78U,0xE69AU,0xD0C4U, 0xACD7U,0x9A89U,0xC06BU,0xF635U,0x75AFU,0x43F1U,0x1913U,0x2F4DU, 0xE135U,0xD76BU,0x8D89U,0xBBD7U,0x384DU,0x0E13U,0x54F1U,0x62AFU, 0x1EBCU,0x28E2U,0x7200U,0x445EU,0xC7C4U,0xF19AU,0xAB78U,0x9D26U, 0x7AF1U,0x4CAFU,0x164DU,0x2013U,0xA389U,0x95D7U,0xCF35U,0xF96BU, 0x8578U,0xB326U,0xE9C4U,0xDF9AU,0x5C00U,0x6A5EU,0x30BCU,0x06E2U, 0xC89AU,0xFEC4U,0xA426U,0x9278U,0x11E2U,0x27BCU,0x7D5EU,0x4B00U, 0x3713U,0x014DU,0x5BAFU,0x6DF1U,0xEE6BU,0xD835U,0x82D7U,0xB489U, 0xA6BCU,0x90E2U,0xCA00U,0xFC5EU,0x7FC4U,0x499AU,0x1378U,0x2526U, 0x5935U,0x6F6BU,0x3589U,0x03D7U,0x804DU,0xB613U,0xECF1U,0xDAAFU, 0x14D7U,0x2289U,0x786BU,0x4E35U,0xCDAFU,0xFBF1U,0xA113U,0x974DU, 0xEB5EU,0xDD00U,0x87E2U,0xB1BCU,0x3226U,0x0478U,0x5E9AU,0x68C4U, 0x8F13U,0xB94DU,0xE3AFU,0xD5F1U,0x566BU,0x6035U,0x3AD7U,0x0C89U, 0x709AU,0x46C4U,0x1C26U,0x2A78U,0xA9E2U,0x9FBCU,0xC55EU,0xF300U, 0x3D78U,0x0B26U,0x51C4U,0x679AU,0xE400U,0xD25EU,0x88BCU,0xBEE2U, 0xC2F1U,0xF4AFU,0xAE4DU,0x9813U,0x1B89U,0x2DD7U,0x7735U,0x416BU, 0xF5E2U,0xC3BCU,0x995EU,0xAF00U,0x2C9AU,0x1AC4U,0x4026U,0x7678U, 0x0A6BU,0x3C35U,0x66D7U,0x5089U,0xD313U,0xE54DU,0xBFAFU,0x89F1U, 0x4789U,0x71D7U,0x2B35U,0x1D6BU,0x9EF1U,0xA8AFU,0xF24DU,0xC413U, 0xB800U,0x8E5EU,0xD4BCU,0xE2E2U,0x6178U,0x5726U,0x0DC4U,0x3B9AU, 0xDC4DU,0xEA13U,0xB0F1U,0x86AFU,0x0535U,0x336BU,0x6989U,0x5FD7U, 0x23C4U,0x159AU,0x4F78U,0x7926U,0xFABCU,0xCCE2U,0x9600U,0xA05EU, 0x6E26U,0x5878U,0x029AU,0x34C4U,0xB75EU,0x8100U,0xDBE2U,0xEDBCU, 0x91AFU,0xA7F1U,0xFD13U,0xCB4DU,0x48D7U,0x7E89U,0x246BU,0x1235U, }; crc = crc ^ 0xFFFFU; while (len > 0) { crc = table[*data ^ (UINT8)crc] ^ (crc >> 8); data++; len--; } crc = crc ^ 0xFFFFU; return crc; } ## Links * [crcmod: a Python module able to generate C code](http://crcmod.sourceforge.net/crcmod.html) * [crcmod: all prdefined CRC supported](http://crcmod.sourceforge.net/crcmod.predefined.html#class-predefinedcrc) * [PyCRC: another Python module](http://pycrc.readthedocs.io/en/latest/readme.html) * [online CRC calculator](http://www.sunshine2k.de/coding/javascript/crc/crc_js.html) @include='bio_andrea_montefusco'
2018 Ⓒ TanzoLab