-2

In my Project i need to append one byte to a data buffer.
If I add this extra byte this would cause a change of the crc checksum.
In order to prevent a change I have to calculate a reconcilation factor which is appended to the end of the data.
The algorithm works for an 32-bit crc. But i have to adjust the algorithm for an 16-bit crc.

I already try to reduce the reconcilation Faktor from 4 to 2 bytes.
And i change the shift value from the index of the crc_revtable from 24 to 8.

32-bit CRC:

void fix_crc_pos(unsigned char *buffer, int length, uint32_t tcrcreg, int fix_pos, uint32_t *crc_table,
        uint32_t *crc_revtable)
{
    int i;
    // make sure fix_pos is within 0..( length -1)
    fix_pos = ((fix_pos % length) + length) % length;

    // calculate crc register at position fix_pos ; this is essentially crc32 ()
    uint32_t crcreg = INITXOR ;
    for (i = 0; i < fix_pos ; ++i) {
        crcreg = (crcreg >> 8) ^ crc_table[((crcreg ^ buffer [i]) & 0xFF)];
    }

    // inject crcreg as content
    for (i = 0; i < 4; ++i)
        buffer[fix_pos + i] = (crcreg >> i * 8) & 0xFF;

    // calculate crc backwards to fix_pos , beginning at the end
    tcrcreg ^= FINALXOR ;
    for (i = length - 1; i >= fix_pos ; --i) {
        tcrcreg = (tcrcreg << 8) ^ crc_revtable[tcrcreg >> 3*8] ^ buffer[i];
    }

    // inject new content
    for (i = 0; i < 4; ++i)
        buffer[fix_pos + i] = (tcrcreg >> i * 8) & 0xFF;
}

16-bit CRC:

void fix_crc_pos(unsigned char * buffer, int length, uint16_t tcrcreg, int fix_pos, uint16_t *crc_table,
                 uint16_t *crc_revtable)
{
    int i;
    // make sure fix_pos is within 0..( length -1)
    fix_pos = ((fix_pos % length) + length) % length;

    // calculate crc register at position fix_pos ; this is essentially crc16 ()
    uint16_t crcreg = INITXOR ;
    for (i = 0; i < fix_pos; ++i) {
        crcreg = (crcreg >> 8) ^ crc_table[((crcreg ^ buffer [i]) & 0xFF)];
    }

    // inject crcreg as content
    for (i = 0; i < 4; ++i)
        buffer[fix_pos + i] = (crcreg >> i * 8) & 0xFF;

    // calculate crc backwards to fix_pos , beginning at the end
    tcrcreg ^= FINALXOR ;
    for (i = length - 1; i >= fix_pos; --i) {
        tcrcreg = (tcrcreg << 8) ^ crc_revtable[tcrcreg >> 8] ^ buffer[i];
    }

    // inject new content
    for (i = 0; i < 4; ++i)
        buffer[fix_pos + i] = (tcrcreg >> i * 8) & 0xFF;
}

Result for the CRC32:

uint32_t crc32_ccitt_table[] = { 0x0000, 0x3096, 0x612C, 0x51BA, 0xC419, 0xF48F, 0xA535, 0x95A3, 0x8832, 0xB8A4, 0xE91E, 0xD988, 0x4C2B, 0x7CBD, 0x2D07, 0x1D91, 0x1064, 0x20F2, 0x7148, 0x41DE, 0xD47D, 0xE4EB, 0xB551, 0x85C7, 0x9856, 0xA8C0, 0xF97A, 0xC9EC, 0x5C4F, 0x6CD9, 0x3D63, 0x0DF5, 0x20C8, 0x105E, 0x41E4, 0x7172, 0xE4D1, 0xD447, 0x85FD, 0xB56B, 0xA8FA, 0x986C, 0xC9D6, 0xF940, 0x6CE3, 0x5C75, 0x0DCF, 0x3D59, 0x30AC, 0x003A, 0x5180, 0x6116, 0xF4B5, 0xC423, 0x9599, 0xA50F, 0xB89E, 0x8808, 0xD9B2, 0xE924, 0x7C87, 0x4C11, 0x1DAB, 0x2D3D, 0x4190, 0x7106, 0x20BC, 0x102A, 0x8589, 0xB51F, 0xE4A5, 0xD433, 0xC9A2, 0xF934, 0xA88E, 0x9818, 0x0DBB, 0x3D2D, 0x6C97, 0x5C01, 0x51F4, 0x6162, 0x30D8, 0x004E, 0x95ED, 0xA57B, 0xF4C1, 0xC457, 0xD9C6, 0xE950, 0xB8EA, 0x887C, 0x1DDF, 0x2D49, 0x7CF3, 0x4C65, 0x6158, 0x51CE, 0x0074, 0x30E2, 0xA541, 0x95D7, 0xC46D, 0xF4FB, 0xE96A, 0xD9FC, 0x8846, 0xB8D0, 0x2D73, 0x1DE5, 0x4C5F, 0x7CC9, 0x713C, 0x41AA, 0x1010, 0x2086, 0xB525, 0x85B3, 0xD409, 0xE49F, 0xF90E, 0xC998, 0x9822, 0xA8B4, 0x3D17, 0x0D81, 0x5C3B, 0x6CAD, 0x8320, 0xB3B6, 0xE20C, 0xD29A, 0x4739, 0x77AF, 0x2615, 0x1683, 0x0B12, 0x3B84, 0x6A3E, 0x5AA8, 0xCF0B, 0xFF9D, 0xAE27, 0x9EB1, 0x9344, 0xA3D2, 0xF268, 0xC2FE, 0x575D, 0x67CB, 0x3671, 0x06E7, 0x1B76, 0x2BE0, 0x7A5A, 0x4ACC, 0xDF6F, 0xEFF9, 0xBE43, 0x8ED5, 0xA3E8, 0x937E, 0xC2C4, 0xF252, 0x67F1, 0x5767, 0x06DD, 0x364B, 0x2BDA, 0x1B4C, 0x4AF6, 0x7A60, 0xEFC3, 0xDF55, 0x8EEF, 0xBE79, 0xB38C, 0x831A, 0xD2A0, 0xE236, 0x7795, 0x4703, 0x16B9, 0x262F, 0x3BBE, 0x0B28, 0x5A92, 0x6A04, 0xFFA7, 0xCF31, 0x9E8B, 0xAE1D, 0xC2B0, 0xF226, 0xA39C, 0x930A, 0x06A9, 0x363F, 0x6785, 0x5713, 0x4A82, 0x7A14, 0x2BAE, 0x1B38, 0x8E9B, 0xBE0D, 0xEFB7, 0xDF21, 0xD2D4, 0xE242, 0xB3F8, 0x836E, 0x16CD, 0x265B, 0x77E1, 0x4777, 0x5AE6, 0x6A70, 0x3BCA, 0x0B5C, 0x9EFF, 0xAE69, 0xFFD3, 0xCF45, 0xE278, 0xD2EE, 0x8354, 0xB3C2, 0x2661, 0x16F7, 0x474D, 0x77DB, 0x6A4A, 0x5ADC, 0x0B66, 0x3BF0, 0xAE53, 0x9EC5, 0xCF7F, 0xFFE9, 0xF21C, 0xC28A, 0x9330, 0xA3A6, 0x3605, 0x0693, 0x5729, 0x67BF, 0x7A2E, 0x4AB8, 0x1B02, 0x2B94, 0xBE37, 0x8EA1, 0xDF1B, 0xEF8D, };

uint32_t crc32_ccitt_table[] = { 0x0000, 0x0641, 0x0AC3, 0x0C82, 0x1586, 0x13C7, 0x1F45, 0x1904, 0x2D4D, 0x2B0C, 0x278E, 0x21CF, 0x38CB, 0x3E8A, 0x3208, 0x3449, 0x5A9A, 0x5CDB, 0x5059, 0x5618, 0x4F1C, 0x495D, 0x45DF, 0x439E, 0x77D7, 0x7196, 0x7D14, 0x7B55, 0x6251, 0x6410, 0x6892, 0x6ED3, 0xB375, 0xB534, 0xB9B6, 0xBFF7, 0xA6F3, 0xA0B2, 0xAC30, 0xAA71, 0x9E38, 0x9879, 0x94FB, 0x92BA, 0x8BBE, 0x8DFF, 0x817D, 0x873C, 0xE9EF, 0xEFAE, 0xE32C, 0xE56D, 0xFC69, 0xFA28, 0xF6AA, 0xF0EB, 0xC4A2, 0xC2E3, 0xCE61, 0xC820, 0xD124, 0xD765, 0xDBE7, 0xDDA6, 0x66EA, 0x60AB, 0x6C29, 0x6A68, 0x736C, 0x752D, 0x79AF, 0x7FEE, 0x4BA7, 0x4DE6, 0x4164, 0x4725, 0x5E21, 0x5860, 0x54E2, 0x52A3, 0x3C70, 0x3A31, 0x36B3, 0x30F2, 0x29F6, 0x2FB7, 0x2335, 0x2574, 0x113D, 0x177C, 0x1BFE, 0x1DBF, 0x04BB, 0x02FA, 0x0E78, 0x0839, 0xD59F, 0xD3DE, 0xDF5C, 0xD91D, 0xC019, 0xC658, 0xCADA, 0xCC9B, 0xF8D2, 0xFE93, 0xF211, 0xF450, 0xED54, 0xEB15, 0xE797, 0xE1D6, 0x8F05, 0x8944, 0x85C6, 0x8387, 0x9A83, 0x9CC2, 0x9040, 0x9601, 0xA248, 0xA409, 0xA88B, 0xAECA, 0xB7CE, 0xB18F, 0xBD0D, 0xBB4C, 0xCB95, 0xCDD4, 0xC156, 0xC717, 0xDE13, 0xD852, 0xD4D0, 0xD291, 0xE6D8, 0xE099, 0xEC1B, 0xEA5A, 0xF35E, 0xF51F, 0xF99D, 0xFFDC, 0x910F, 0x974E, 0x9BCC, 0x9D8D, 0x8489, 0x82C8, 0x8E4A, 0x880B, 0xBC42, 0xBA03, 0xB681, 0xB0C0, 0xA9C4, 0xAF85, 0xA307, 0xA546, 0x78E0, 0x7EA1, 0x7223, 0x7462, 0x6D66, 0x6B27, 0x67A5, 0x61E4, 0x55AD, 0x53EC, 0x5F6E, 0x592F, 0x402B, 0x466A, 0x4AE8, 0x4CA9, 0x227A, 0x243B, 0x28B9, 0x2EF8, 0x37FC, 0x31BD, 0x3D3F, 0x3B7E, 0x0F37, 0x0976, 0x05F4, 0x03B5, 0x1AB1, 0x1CF0, 0x1072, 0x1633, 0xAD7F, 0xAB3E, 0xA7BC, 0xA1FD, 0xB8F9, 0xBEB8, 0xB23A, 0xB47B, 0x8032, 0x8673, 0x8AF1, 0x8CB0, 0x95B4, 0x93F5, 0x9F77, 0x9936, 0xF7E5, 0xF1A4, 0xFD26, 0xFB67, 0xE263, 0xE422, 0xE8A0, 0xEEE1, 0xDAA8, 0xDCE9, 0xD06B, 0xD62A, 0xCF2E, 0xC96F, 0xC5ED, 0xC3AC, 0x1E0A, 0x184B, 0x14C9, 0x1288, 0x0B8C, 0x0DCD, 0x014F, 0x070E, 0x3347, 0x3506, 0x3984, 0x3FC5, 0x26C1, 0x2080, 0x2C02, 0x2A43, 0x4490, 0x42D1, 0x4E53, 0x4812, 0x5116, 0x5757, 0x5BD5, 0x5D94, 0x69DD, 0x6F9C, 0x631E, 0x655F, 0x7C5B, 0x7A1A, 0x7698, 0x70D9, };

unchanged data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x0 0x0 0x0 0x0 0x0

changed data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x8 0x0 0x0 0x0 0x0

CRC-32 before change: 0x90106CEE

CRC-32 after change: 0xA060272F

fixed data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x8 0x32 0x88 0xDB 0xE

CRC-32 after fix: 0x90106CEE

Result for the CRC16:
CRC Table forward: uint32_t crc16_ccitt_table[] = { 0x0000, 0x17CE, 0x0FDF, 0x1811, 0x1FBE, 0x0870, 0x1061, 0x07AF, 0x1F3F, 0x08F1, 0x10E0, 0x072E, 0x0081, 0x174F, 0x0F5E, 0x1890, 0x1E3D, 0x09F3, 0x11E2, 0x062C, 0x0183, 0x164D, 0x0E5C, 0x1992, 0x0102, 0x16CC, 0x0EDD, 0x1913, 0x1EBC, 0x0972, 0x1163, 0x06AD, 0x1C39, 0x0BF7, 0x13E6, 0x0428, 0x0387, 0x1449, 0x0C58, 0x1B96, 0x0306, 0x14C8, 0x0CD9, 0x1B17, 0x1CB8, 0x0B76, 0x1367, 0x04A9, 0x0204, 0x15CA, 0x0DDB, 0x1A15, 0x1DBA, 0x0A74, 0x1265, 0x05AB, 0x1D3B, 0x0AF5, 0x12E4, 0x052A, 0x0285, 0x154B, 0x0D5A, 0x1A94, 0x1831, 0x0FFF, 0x17EE, 0x0020, 0x078F, 0x1041, 0x0850, 0x1F9E, 0x070E, 0x10C0, 0x08D1, 0x1F1F, 0x18B0, 0x0F7E, 0x176F, 0x00A1, 0x060C, 0x11C2, 0x09D3, 0x1E1D, 0x19B2, 0x0E7C, 0x166D, 0x01A3, 0x1933, 0x0EFD, 0x16EC, 0x0122, 0x068D, 0x1143, 0x0952, 0x1E9C, 0x0408, 0x13C6, 0x0BD7, 0x1C19, 0x1BB6, 0x0C78, 0x1469, 0x03A7, 0x1B37, 0x0CF9, 0x14E8, 0x0326, 0x0489, 0x1347, 0x0B56, 0x1C98, 0x1A35, 0x0DFB, 0x15EA, 0x0224, 0x058B, 0x1245, 0x0A54, 0x1D9A, 0x050A, 0x12C4, 0x0AD5, 0x1D1B, 0x1AB4, 0x0D7A, 0x156B, 0x02A5, 0x1021, 0x07EF, 0x1FFE, 0x0830, 0x0F9F, 0x1851, 0x0040, 0x178E, 0x0F1E, 0x18D0, 0x00C1, 0x170F, 0x10A0, 0x076E, 0x1F7F, 0x08B1, 0x0E1C, 0x19D2, 0x01C3, 0x160D, 0x11A2, 0x066C, 0x1E7D, 0x09B3, 0x1123, 0x06ED, 0x1EFC, 0x0932, 0x0E9D, 0x1953, 0x0142, 0x168C, 0x0C18, 0x1BD6, 0x03C7, 0x1409, 0x13A6, 0x0468, 0x1C79, 0x0BB7, 0x1327, 0x04E9, 0x1CF8, 0x0B36, 0x0C99, 0x1B57, 0x0346, 0x1488, 0x1225, 0x05EB, 0x1DFA, 0x0A34, 0x0D9B, 0x1A55, 0x0244, 0x158A, 0x0D1A, 0x1AD4, 0x02C5, 0x150B, 0x12A4, 0x056A, 0x1D7B, 0x0AB5, 0x0810, 0x1FDE, 0x07CF, 0x1001, 0x17AE, 0x0060, 0x1871, 0x0FBF, 0x172F, 0x00E1, 0x18F0, 0x0F3E, 0x0891, 0x1F5F, 0x074E, 0x1080, 0x162D, 0x01E3, 0x19F2, 0x0E3C, 0x0993, 0x1E5D, 0x064C, 0x1182, 0x0912, 0x1EDC, 0x06CD, 0x1103, 0x16AC, 0x0162, 0x1973, 0x0EBD, 0x1429, 0x03E7, 0x1BF6, 0x0C38, 0x0B97, 0x1C59, 0x0448, 0x1386, 0x0B16, 0x1CD8, 0x04C9, 0x1307, 0x14A8, 0x0366, 0x1B77, 0x0CB9, 0x0A14, 0x1DDA, 0x05CB, 0x1205, 0x15AA, 0x0264, 0x1A75, 0x0DBB, 0x152B, 0x02E5, 0x1AF4, 0x0D3A, 0x0A95, 0x1D5B, 0x054A, 0x1284, };

CRC Table reverse: uint32_t crc16_ccitt_table[] = { 0x0000, 0x2043, 0x4086, 0x60C5, 0x810C, 0xA14F, 0xC18A, 0xE1C9, 0x225B, 0x0218, 0x62DD, 0x429E, 0xA357, 0x8314, 0xE3D1, 0xC392, 0x44B6, 0x64F5, 0x0430, 0x2473, 0xC5BA, 0xE5F9, 0x853C, 0xA57F, 0x66ED, 0x46AE, 0x266B, 0x0628, 0xE7E1, 0xC7A2, 0xA767, 0x8724, 0x896C, 0xA92F, 0xC9EA, 0xE9A9, 0x0860, 0x2823, 0x48E6, 0x68A5, 0xAB37, 0x8B74, 0xEBB1, 0xCBF2, 0x2A3B, 0x0A78, 0x6ABD, 0x4AFE, 0xCDDA, 0xED99, 0x8D5C, 0xAD1F, 0x4CD6, 0x6C95, 0x0C50, 0x2C13, 0xEF81, 0xCFC2, 0xAF07, 0x8F44, 0x6E8D, 0x4ECE, 0x2E0B, 0x0E48, 0x329B, 0x12D8, 0x721D, 0x525E, 0xB397, 0x93D4, 0xF311, 0xD352, 0x10C0, 0x3083, 0x5046, 0x7005, 0x91CC, 0xB18F, 0xD14A, 0xF109, 0x762D, 0x566E, 0x36AB, 0x16E8, 0xF721, 0xD762, 0xB7A7, 0x97E4, 0x5476, 0x7435, 0x14F0, 0x34B3, 0xD57A, 0xF539, 0x95FC, 0xB5BF, 0xBBF7, 0x9BB4, 0xFB71, 0xDB32, 0x3AFB, 0x1AB8, 0x7A7D, 0x5A3E, 0x99AC, 0xB9EF, 0xD92A, 0xF969, 0x18A0, 0x38E3, 0x5826, 0x7865, 0xFF41, 0xDF02, 0xBFC7, 0x9F84, 0x7E4D, 0x5E0E, 0x3ECB, 0x1E88, 0xDD1A, 0xFD59, 0x9D9C, 0xBDDF, 0x5C16, 0x7C55, 0x1C90, 0x3CD3, 0x6536, 0x4575, 0x25B0, 0x05F3, 0xE43A, 0xC479, 0xA4BC, 0x84FF, 0x476D, 0x672E, 0x07EB, 0x27A8, 0xC661, 0xE622, 0x86E7, 0xA6A4, 0x2180, 0x01C3, 0x6106, 0x4145, 0xA08C, 0x80CF, 0xE00A, 0xC049, 0x03DB, 0x2398, 0x435D, 0x631E, 0x82D7, 0xA294, 0xC251, 0xE212, 0xEC5A, 0xCC19, 0xACDC, 0x8C9F, 0x6D56, 0x4D15, 0x2DD0, 0x0D93, 0xCE01, 0xEE42, 0x8E87, 0xAEC4, 0x4F0D, 0x6F4E, 0x0F8B, 0x2FC8, 0xA8EC, 0x88AF, 0xE86A, 0xC829, 0x29E0, 0x09A3, 0x6966, 0x4925, 0x8AB7, 0xAAF4, 0xCA31, 0xEA72, 0x0BBB, 0x2BF8, 0x4B3D, 0x6B7E, 0x57AD, 0x77EE, 0x172B, 0x3768, 0xD6A1, 0xF6E2, 0x9627, 0xB664, 0x75F6, 0x55B5, 0x3570, 0x1533, 0xF4FA, 0xD4B9, 0xB47C, 0x943F, 0x131B, 0x3358, 0x539D, 0x73DE, 0x9217, 0xB254, 0xD291, 0xF2D2, 0x3140, 0x1103, 0x71C6, 0x5185, 0xB04C, 0x900F, 0xF0CA, 0xD089, 0xDEC1, 0xFE82, 0x9E47, 0xBE04, 0x5FCD, 0x7F8E, 0x1F4B, 0x3F08, 0xFC9A, 0xDCD9, 0xBC1C, 0x9C5F, 0x7D96, 0x5DD5, 0x3D10, 0x1D53, 0x9A77, 0xBA34, 0xDAF1, 0xFAB2, 0x1B7B, 0x3B38, 0x5BFD, 0x7BBE, 0xB82C, 0x986F, 0xF8AA, 0xD8E9, 0x3920, 0x1963, 0x79A6, 0x59E5, };

unchanged Data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x0 0x0 0x0 0x0

changed Data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x8 0x0 0x0 0x0

CRC for unchanged data: 0xEA83

CRC for changed data: 0xFCD9

Fixed data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x8 0xA4 0xFB 0x0

CRC fixed: 0xFAC4

Philipp Fu
  • 75
  • 1
  • 6
  • You show only the low 16 bits of each 32-bit entry of your 32-bit CRC tables. – Mark Adler Jan 05 '23 at 01:23
  • Two obvious errors are that you are "injecting" four bytes in the 16-bit version. It should be two bytes: `for (i = 0; i < 2; ++i)`. This occurs twice in that routine. – Mark Adler Jan 05 '23 at 08:31
  • Did you make that 16-bit CRC table? It looks like you used the polynomial `0x1021`, and computed a reflected CRC, but you did not reflect the polynomial. The reflected polynomial that you should have used would be `0x8408`. Or did you want a _non-_ reflected CRC? In which case the table was also incorrectly generated. Do you have a definition of the 16-bit CRC you want/need to use? – Mark Adler Jan 05 '23 at 08:58

1 Answers1

0

I don't have time to fully check this now, but try putting the correcting bytes at the end of the array (they might need to be swapped also):

Fixed data:
0x0 0x1 0x2 0x3 0x4
0x5 0x6 0x7 0x8 0x9
0xA 0xB 0xC 0xD 0xE
0xF 0x0 0x1 0x2 0x3
0x8 0x0 0xA4 0xFB
rcgldr
  • 27,407
  • 3
  • 36
  • 61