Guía

Qué es un CRC y cómo elegir sus parámetros

Entiende qué detecta un CRC, por qué el nombre CRC-16 no basta y cómo elegir polinomio, init, reflexión, xorout y orden de bytes.

por Tools in a Tab · Publicado el · Revisado el

Respuesta breve

Un CRC, o comprobación de redundancia cíclica, produce un valor corto a partir de una secuencia de bits. Se utiliza para detectar determinados errores accidentales en tramas, archivos o bloques de almacenamiento. No cifra los datos y no demuestra quién los creó.

Elegir «CRC-16» no define un algoritmo completo. Dos modelos de 16 bits pueden usar distinto polinomio, valor inicial, reflexión o XOR final y producir resultados diferentes para los mismos bytes.

El modelo completo, no solo la anchura

Antes de implementar o comprobar un CRC, reúne estos datos:

Parámetro Pregunta que resuelve
width ¿Cuántos bits tiene el registro y el resultado?
poly ¿Qué polinomio generador se utiliza?
init ¿Con qué valor empieza el registro?
refin ¿Se reflejan los bits de cada byte de entrada?
refout ¿Se refleja el registro antes del XOR final?
xorout ¿Qué máscara se aplica al terminar?
check ¿Qué debe producir el vector de prueba 123456789?

También debes saber qué bytes cubre el cálculo y cómo se coloca el resultado en el mensaje. Esos dos aspectos pertenecen al protocolo, no quedan resueltos por decir el nombre del CRC.

Por qué «CRC-16» es ambiguo

La cadena ASCII 123456789 es un vector de comprobación habitual. Con dos modelos de 16 bits produce:

Modelo Polinomio init Reflejado Resultado
CRC-16/ARC 0x8005 0x0000 0xBB3D
CRC-16/IBM-3740 0x1021 0xFFFF no 0x29B1

Ambos resultados tienen 16 bits y ambos son correctos para su contrato. Si la documentación solo dice «CRC-16», todavía falta información.

Puedes comparar estos modelos con la calculadora CRC, que muestra todos los parámetros del preset activo.

Qué hace el polinomio

Un CRC interpreta la secuencia como un polinomio binario y calcula un resto en aritmética módulo 2. El parámetro poly describe el divisor. En la notación habitual se omite el término principal, porque viene determinado por la anchura.

Por ejemplo, para 16 bits:

poly 0x1021 → x^16 + x^12 + x^5 + 1

No intercambies la representación normal con una forma reflejada que aparezca en el código de otra implementación. 0x8005 y 0xA001 pueden estar relacionados por la orientación de bits, pero no se pegan indistintamente en un campo sin saber qué convención espera.

Inicio, reflexión y XOR final

init llena el registro antes de procesar el primer byte. Empezar en cero o en todos unos cambia el resultado incluso cuando el polinomio coincide.

refin define el orden con el que entran los bits de cada byte. refout describe la orientación del registro antes de aplicar xorout. La reflexión de bits no es lo mismo que invertir el orden de los bytes resultantes.

xorout aplica una máscara al final. Por eso comparar únicamente el bucle interno de dos implementaciones no garantiza que implementen el mismo modelo.

CRC-32 y CRC-32C son modelos distintos

El nombre también puede confundirse en 32 bits:

CRC-32/ISO-HDLC sobre "123456789" = 0xCBF43926
CRC-32C sobre "123456789"         = 0xE3069283

CRC-32C usa el polinomio de Castagnoli y no es un alias de CRC-32/ISO-HDLC. El RFC 9260 especifica CRC-32C para SCTP. RFC 1662 documenta FCS de 16 y 32 bits utilizados en PPP.

Elige los parámetros desde la autoridad correcta

Sigue este orden:

  1. Identifica la versión exacta del protocolo, formato o dispositivo.
  2. Busca su especificación oficial o la hoja de datos del fabricante.
  3. Copia el nombre canónico y todos los parámetros, no una etiqueta abreviada.
  4. Confirma qué bytes entran y en qué orden.
  5. Comprueba el vector 123456789 si la especificación lo proporciona.
  6. Verifica al menos una trama real publicada por esa misma autoridad.
  7. Documenta el orden de transmisión del resultado.

Una calculadora sirve para reproducir un contrato conocido. No puede deducir con fiabilidad qué modelo quiso decir una documentación incompleta.

Ejemplo: CRC-16/MODBUS y orden de bytes

Los bytes hexadecimales 02 07 producen el valor numérico 0x1241 con CRC-16/MODBUS. Sin embargo, Modbus RTU transmite primero el byte menos significativo:

Valor CRC:          0x1241
Orden visual MSB:   12 41
Orden Modbus LSB:   41 12

Invertir bytes no cambia el valor matemático, pero sí cómo se serializa en la trama. La especificación Modbus Serial Line define tanto el cálculo como este orden de transmisión.

Texto y bytes no son lo mismo

El CRC siempre procesa bytes. Si escribes 02 07 en modo texto, calcularás los caracteres 0, 2, espacio, 0, 7; no los bytes 0x02 y 0x07.

Para texto también debes acordar la codificación. La letra é en UTF-8 puede estar representada como C3 A9, mientras una secuencia visualmente equivalente puede usar 65 CC 81. Si los bytes difieren, el CRC debe diferir.

Antes de comparar resultados registra:

  • la secuencia hexadecimal exacta;
  • la codificación y normalización, si el origen es texto;
  • si se incluyen cabeceras, longitudes, direcciones o el propio campo CRC;
  • el orden de los bytes multibyte.

Qué errores puede detectar

La capacidad de detección depende del polinomio, la longitud de los mensajes y el patrón de error. Un CRC bien elegido puede detectar todos los errores de ciertos tipos hasta límites definidos, pero no existe una garantía genérica que se aplique por igual a cualquier polinomio y longitud.

Por eso no conviene inventar parámetros solo porque producen un valor de 16 o 32 bits. Utiliza el modelo estudiado y exigido por el sistema con el que debes interoperar.

Un CRC no aporta seguridad criptográfica

No hay una clave secreta. Quien modifica un mensaje puede calcular el CRC nuevo, así que el receptor no puede distinguir una alteración deliberada de un mensaje legítimo. Un CRC tampoco oculta datos ni prueba la identidad del remitente.

Para integridad frente a un atacante se necesita un mecanismo autenticado, como un MAC o una firma dentro de un protocolo adecuado. Un hash SHA-256 es útil para identificar contenido, pero por sí solo tampoco autentica al remitente.

Checklist de interoperabilidad

  • Anchura, polinomio, init, refin, refout y xorout coinciden.
  • La forma del polinomio usa la convención esperada por la implementación.
  • El vector 123456789 produce el valor de comprobación correcto.
  • Ambas partes procesan exactamente los mismos bytes.
  • La codificación del texto está fijada.
  • El resultado ocupa el número correcto de bits y ceros iniciales.
  • El orden de transmisión del CRC está documentado.
  • El CRC se usa para errores accidentales, no como autenticación.

La calculadora de Tools in a Tab procesa texto UTF-8 o bytes hexadecimales localmente. Incluye presets y parámetros personalizados de 8 a 64 bits, pero la selección final debe proceder siempre de la especificación que gobierna tu sistema.