#define BIT(x)  ((x) >= 32u ? 0 : 1lu << (x))
#define x(b)    BIT(16-1-(b))
#define P16_1   (x(16)+x(15)+x(2)+x(0))
#define P16_2   (x(16)+x(12)+x(5)+x(0))
#define P16_3   (x(16)+x(14)+x(13)+x(11)+x(0))

unsigned short  crc_16_tab [256];

void
init_tab_16 ( unsigned short poly)
{
    unsigned short  t = poly;
    int             i;
    int             j;

    memset ( crc_16_tab, 0, sizeof(crc_16_tab) );

    j = 0x80;
    do {
        i = 0x100;
        do {
            if ( --i & j )
                crc_16_tab [i] ^= t;
        } while (i);
        t = (t >> 1) ^ (t & 1  ?  poly  :  0);
    } while ( j >>= 1 );
}

unsigned short
chsum_16 ( const unsigned char* s, size_t len, unsigned short crc )
{
    while ( len-- )
        crc = crc_16_tab [(unsigned char)(*s++ ^ crc)] ^ (crc >> 8);

    return crc;
}