Cálculo de CRC

He estado tratando de entender el cálculo de CRC. He encontrado un calculador de CRC en línea y he hecho un experimento.

He intentado calcular con esta calculadora el CRC16-CCITT (en la calculadora he especificado: valor inicial 0 , valor xor final 0 ) para datos con una longitud igual a un byte (es decir, 0x31). Esperaba recibir el byte de datos, es decir, 0x31. La razón de esta expectativa se basó en el hecho de que CRC es básicamente un recordatorio de la división de polinomios. Mi "mensaje" tiene una longitud de un byte, por lo que es un polinomio de grado 7 (como máximo) y el polinomio CRC16 es un polinomio de grado 12 (según la calculadora), por lo que el resto de la división del polinomio de grado 7 por polinomio de grado 12 tiene que ser un polinomio de grado 7.

Me sorprendió que la calculadora me diera un valor de CRC igual a 0x2672. ¿Alguien puede explicarme la discrepancia? Gracias de antemano.

¿Le gustaría explicar por qué espera recuperar el byte de datos? ¿Intentó buscar cómo se calcula exactamente el CRC16-CCITT?
@Justme gracias por tu reacción. Acabo de intentar explicar por qué tenía la expectativa.
¿Puede explicar por qué cree que es una discrepancia? ¿Qué esperabas que pasara?

Respuestas (1)

Básicamente, ser un resto no significa que realmente lo sea, solo significa que el concepto es el mismo, pero no con los números tradicionales y en decimal, sino en Galois Field para números de base 2. Pero también hay una explicación más sencilla.

Calcular un valor de CRC no se trata simplemente de introducir datos, también hay otras especificaciones.

El valor está inicialmente preestablecido en algún valor semilla predefinido. Por lo general, este valor no es cero y, muy típicamente, el valor inicial es todos los bits establecidos en uno. CRC-CCITT en realidad no define esto, y varias implementaciones usan diferentes valores iniciales. En términos de cálculo de CRC, también se puede pensar en lo mismo que comenzar con un valor inicial de 0, pero alimentando dos bytes de datos iniciales para que el valor inicial sea correcto.

Después de procesar los bytes de datos, generalmente hay un paso final para XOR el valor CRC con un valor XOR final predefinido. También varía entre diferentes implementaciones.

Otras especificaciones también difieren, como si los datos se introducen primero en el algoritmo CRC MSB o LSB.

Así es como funciona el algoritmo en la calculadora CRC. Verificado con el método de lápiz y papel.

0x31 es el único byte de datos introducido.

0x0000 es el valor CRC inicial.

Por lo tanto, como esta versión del algoritmo ejecuta MSB primero, los datos CRC deben ingresarse al registro CRC para que el MSB de los datos se procese inmediatamente y los cambios de bit CRC se realicen hacia la izquierda. Por lo tanto, DATA xor CRC es:

0x3100 CRC register xored with data, no shift rounds yet

0x6200 After round 1
0xC400 After round 2
0x9821 After round 3
0x2063 After round 4
0x40C6 After round 5
0x818C After round 6
0x1339 After round 7
0x2672 After round 8

Entonces, el resultado de hacer el algoritmo con polinomio de 0x1021, con valor inicial de 0x0000, xor final de 0x0000, y procesando primero los datos de entrada MSB, el valor CRC realmente es 0x2672.

Gracias por su respuesta. He leído sobre las otras especificaciones utilizadas durante el cálculo de CRC. Con este conocimiento en mente, he especificado el valor inicial 0, el valor xor final 0 en la calculadora. El hecho de que recibí CRC 0x2672 en lugar de 0x31 fue aún más sorprendente para mí. ¿Qué esperaría como CRC resultante en las condiciones que he descrito?
Agregué la verificación a mi respuesta. Con esa calculadora, el valor esperado realmente es 0x2672.
El problema está en mi comprensión incorrecta del proceso de cálculo de CRC. ¿Puede decirme por qué el algoritmo comienza con el valor 0x3100 en el registro CRC y no con 0x0031?
Lo segundo que no entiendo por qué el polinomio X dieciséis + X 12 + X 5 + 1 está codificado como 0x1021? Yo esperaría el X 12 + X 5 + 1 polinomio para 0x1021. Gracias.
Pero ya expliqué por qué los datos 0x31 van al registro CRC como 0x3100. Si fuera al registro CRC como 0x0031, primero se procesarían 8 bits irrelevantes que no son de datos, y el valor CRC sería 0x3100 después del procesamiento. Y un CRC de 16 bits se calcula con un polinomio de 17 bits (pero no debe preguntarse en un comentario sino como una pregunta separada), se puede averiguar leyendo un tutorial sobre cómo funcionan los CRC o la página de Wikipedia.