Como configurar o cálculo da tabela CRC

Existem muitos exemplos de cálculo de CRC por aí. Implementações simples com deslocamento de bits e mais eficientes com uma tabela pré-calculada. Mas também existem muitos parâmetros de um CRC ao lado do polinômio que afetam o cálculo. Você pode avaliar estes parâmetros aqui:http://zorc.breitbandkatze.de/crc.html

Esses parâmetros são

valor inicial de CRCreflexão dos dados de entradareflexão dos dados de saídavalor XOR final para CRC

Para alguns algoritmos CRC "padrão", esses parâmetros são bem definidos, como o CRC-16 (CCITT). Mas existem algumas implementações que usam parâmetros diferentes.

Minha implementação deve ser compatível com um CRC16 com um polinômio CCITT (x16 + x12$12reflexão dos dados de saída13$

Como os parâmetros de reflexão do CRC podem ser calculados no método de inicialização?

Editar: Como devo fazer para controlar cada um dos parâmetros individualmente? Eu gostaria de entender como oInit função realmente funciona e como todos os parâmetros são implementados.

typedef unsigned char uint8_t;
typedef unsigned short crc;

crc  crcTable[256];
#define WIDTH  (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
#define POLYNOMIAL 0x1021

template<typename t>
t reflect(t v)
{
    t r = 0;

    for (int i = 0; i < (8 * sizeof v); ++i)
    {
        r <<= 1;
        r |= v&1;
        v >>= 1;
    }

    return r;
}

void Init()
{
    crc  remainder;

    for (int dividend = 0; dividend < 256; ++dividend)
    {
        remainder = dividend << (WIDTH - 8);

        for (uint8_t bit = 8; bit > 0; --bit)
        {
            if (remainder & TOPBIT)
                remainder = (remainder << 1) ^ POLYNOMIAL;
            else
                remainder = (remainder << 1);
        }

        crcTable[dividend] = remainder;
    }
}

crc Calculate(const uint8_t *message, int nBytes, crc wOldCRC)
{
    uint8_t data;
    crc remainder = wOldCRC;

    for (int byte = 0; byte < nBytes; ++byte)
    {
        data = reflect(message[byte]) ^ (remainder >> (WIDTH - 8));
        remainder = crcTable[data] ^ (remainder << 8);
    }

    return reflect(remainder);
}

int main()
{
    crc expected = 0x6f91;
    uint8_t pattern[] = "123456789";

    Init();
    crc result = Calculate(pattern, 9, 0xFFFF);

    if (result != expected)
    {
        // this output is not relevant to the question, despite C++ tag
        printf("CRC 0x%04x wrong, expected 0x%04x\n", result, expected);
    }
}