O polinômio para CRC32 é:
x 32 + x 26 + x 23 + x 22 + x 16 + x 12 + x 11 + x 10 + x 8 + x 7 + x 5 + x 4 + x 2 + x + 1
Ou em hexadecimal e binário:
0x 01 04 C1 1D B7
1 0000 0100 1100 0001 0001 1101 1011 0111
O termo mais alto (x 32 ) geralmente não é escrito explicitamente, então pode ser representado em hexadecimal
0x 04 C1 1D B7
Sinta-se à vontade para contar os 1s e 0s, mas você descobrirá que eles correspondem ao polinômio, onde 1
é o bit 0 (ou o primeiro bit) e x
é o bit 1 (ou o segundo bit).
Por que esse polinômio? Porque é necessário que haja um determinado polinômio padrão e o padrão foi definido pelo IEEE 802.3. Além disso, é extremamente difícil encontrar um polinômio que detecte erros de bits diferentes com eficácia.
Você pode pensar no CRC-32 como uma série de "Aritmética Binária sem Cargas" ou basicamente "XOR e operações de deslocamento". Isso é tecnicamente chamado de aritmética polinomial.
Para entender melhor, pense nesta multiplicação:
(x^3 + x^2 + x^0)(x^3 + x^1 + x^0)
= (x^6 + x^4 + x^3
+ x^5 + x^3 + x^2
+ x^3 + x^1 + x^0)
= x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0
Se assumirmos que x é a base 2, obteremos:
x^7 + x^3 + x^2 + x^1 + x^0
Por quê? Como 3x ^ 3 é 11x ^ 11 (mas precisamos apenas de 1 ou 0 pré-dígito), transferimos:
=1x^110 + 1x^101 + 1x^100 + 11x^11 + 1x^10 + 1x^1 + x^0
=1x^110 + 1x^101 + 1x^100 + 1x^100 + 1x^11 + 1x^10 + 1x^1 + x^0
=1x^110 + 1x^101 + 1x^101 + 1x^11 + 1x^10 + 1x^1 + x^0
=1x^110 + 1x^110 + 1x^11 + 1x^10 + 1x^1 + x^0
=1x^111 + 1x^11 + 1x^10 + 1x^1 + x^0
Mas os matemáticos mudaram as regras para que seja o mod 2. Então, basicamente, qualquer mod 2 polinomial binário é apenas uma adição sem carry ou XORs. Portanto, nossa equação original se parece com:
=( 1x^110 + 1x^101 + 1x^100 + 11x^11 + 1x^10 + 1x^1 + x^0 ) MOD 2
=( 1x^110 + 1x^101 + 1x^100 + 1x^11 + 1x^10 + 1x^1 + x^0 )
= x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0 (or that original number we had)
Sei que isso é um ato de fé, mas está além da minha capacidade como programador de linha. Se você é um estudante de ciência da computação ou engenheiro, eu o desafio a decifrar isso. Todos se beneficiarão com esta análise.
Então, para trabalhar um exemplo completo:
Original message : 1101011011
Polynomial of (W)idth 4 : 10011
Message after appending W zeros : 11010110110000
Agora dividimos a Mensagem aumentada pelo Poli usando aritmética CRC. Esta é a mesma divisão de antes:
1100001010 = Quotient (nobody cares about the quotient)
_______________
10011 ) 11010110110000 = Augmented message (1101011011 + 0000)
=Poly 10011,,.,,....
-----,,.,,....
10011,.,,....
10011,.,,....
-----,.,,....
00001.,,....
00000.,,....
-----.,,....
00010,,....
00000,,....
-----,,....
00101,....
00000,....
-----,....
01011....
00000....
-----....
10110...
10011...
-----...
01010..
00000..
-----..
10100.
10011.
-----.
01110
00000
-----
1110 = Remainder = THE CHECKSUM!!!!
A divisão produz um quociente, que descartamos, e um resto, que é o checksum calculado. Isso encerra o cálculo. Normalmente, a soma de verificação é então anexada à mensagem e o resultado transmitido. Nesse caso, a transmissão seria: 11010110111110.
Use apenas um número de 32 bits como seu divisor e use todo o seu fluxo como seu dividendo. Jogue fora o quociente e guarde o restante. Pegue o restante no final de sua mensagem e você terá um CRC32.
Avaliação de cara comum:
QUOTIENT
----------
DIVISOR ) DIVIDEND
= REMAINDER
- Pegue os primeiros 32 bits.
- Bits de deslocamento
- Se 32 bits forem inferiores a DIVISOR, vá para a etapa 2.
- XOR 32 bits da DIVISOR. Vá para a etapa 2.
(Observe que o fluxo deve ser divisível por 32 bits ou deve ser preenchido. Por exemplo, um fluxo ANSI de 8 bits teria que ser preenchido. Também no final do fluxo, a divisão é interrompida.)
0xEDB88320
também pode ser escrito msbit-first ( normal ) como0x04C11DB7
. Os valores da tabela que você encontrou em outro lugar foram gerados usando o mesmo polinômio CRC?