FirmGod

CRC 계산기

CRC-8, CRC-16, CRC-32를 표준 모델이나 직접 지정한 다항식·초기값·반사·최종 XOR로 계산합니다. CRC 카탈로그의 검증값으로 확인했습니다.

UTF-8 바이트로 인코딩합니다.

CRC-80xF4
10진수244
2진수11110100
바이트, 하위 먼저F4
메시지 길이9 bytes

모델 파라미터

폭8 bits
다항식0x7
초기값0x00
최종 XOR0x00
입력 반사no
출력 반사no

Check value for "123456789" is 0xF4 — this implementation matches it.

CRC가 하는 일

CRC는 데이터를 하나의 큰 이진수로 보고 정해진 다항식으로 나눈 나머지입니다. 보내는 쪽이 그 나머지를 덧붙이고 받는 쪽이 같은 계산을 반복해 값이 맞는지 봅니다. 나눗셈이라고 하지만 실제 구현은 XOR과 시프트로 이루어지며, 그래서 8비트 마이크로컨트롤러에서도 부담 없이 돌아갑니다.

체크섬을 단순히 더하는 방식보다 훨씬 강합니다. 덧셈 체크섬은 바이트 두 개의 순서가 바뀌어도 값이 같지만, CRC는 위치에 따라 기여가 달라져 그런 오류까지 잡아냅니다.

네 가지 파라미터가 모델을 정합니다

"CRC-16을 쓴다"는 말만으로는 값을 재현할 수 없습니다. 모델을 정하는 것은 다음 네 가지입니다.

  • 다항식 — 나눗셈에 쓰는 상수. 폭에 따라 8비트, 16비트, 32비트 값입니다.
  • 초기값 — 레지스터의 시작 상태. 0x0000과 0xFFFF가 흔하고 결과는 완전히 다릅니다.
  • 반사 — 입력 바이트와 출력 레지스터를 각각 뒤집을지 여부. 둘은 독립적입니다.
  • 최종 XOR — 마지막에 결과에 XOR할 값. 0 또는 전부 1이 대부분입니다.

이 네 가지를 적어 두는 표기를 Rocksoft 모델이라고 부릅니다. 어떤 CRC를 다른 사람에게 설명해야 한다면 이름 대신 이 네 값을 적어 주는 편이 정확합니다.

정방향 표기와 역방향 표기

같은 다항식이 자료마다 다른 숫자로 적혀 있는 일이 자주 있습니다. CRC-16/MODBUS의 다항식은 0x8005이지만 구현 코드에는 0xA001로 등장합니다. 두 값은 비트를 뒤집은 관계이고, 반사 구현에서는 역방향 상수를 쓰는 편이 시프트 방향과 맞아 편리하기 때문입니다.

CRC-32도 마찬가지로 0x04C11DB7과 0xEDB88320이 같은 다항식입니다. 이 계산기는 정방향 표기를 받으므로, 코드에서 역방향 상수를 가져왔다면 뒤집어서 넣어야 같은 결과가 나옵니다.

구현을 검증하는 방법

CRC 카탈로그는 모든 표준 모델에 대해 문자열 123456789의 결과를 검증값으로 제공합니다. 직접 구현한 코드가 그 값을 내면 파라미터를 올바로 해석한 것입니다. 이 사이트의 표준 모델도 같은 값으로 확인했습니다.

값이 어긋난다면 보통 원인은 세 가지 중 하나입니다. 역방향 다항식을 정방향 자리에 넣었거나, 반사 설정이 반대이거나, 초기값을 0으로 두었는데 모델은 0xFFFF를 요구하는 경우입니다.

무엇을 잡고 무엇을 못 잡나

CRC-16은 단일 비트 오류, 두 비트 오류, 홀수 개의 비트 오류, 그리고 16비트 이하의 연속된 오류 구간을 모두 잡아냅니다. 그보다 긴 오류 구간은 확률적으로 통과할 수 있지만 그 확률은 매우 낮습니다.

의도적인 변조는 다른 문제입니다. 원하는 CRC가 나오도록 데이터를 조작하는 것은 계산상 간단합니다. CRC는 회선 잡음을 잡기 위한 것이지 공격자를 막기 위한 것이 아닙니다. 변조를 막아야 한다면 키를 사용하는 메시지 인증 코드를 써야 합니다.

어떤 모델을 고를지 정해져 있는 경우

새 프로토콜을 설계하는 것이 아니라면 모델은 이미 정해져 있습니다. 모드버스 RTU는 CRC-16/MODBUS, 이더넷과 ZIP은 CRC-32, CAN은 CRC-15, 1-Wire 장치는 CRC-8/MAXIM을 씁니다. 상대 장비가 무엇을 기대하는지가 기준이고, 선택의 여지는 없습니다.

모드버스만 다룬다면 모드버스 CRC16 계산기가 파라미터를 고를 필요 없이 바로 결과를 냅니다.

자주 묻는 질문

같은 CRC-16인데 값이 다릅니다.

CRC-16이라는 이름은 모델을 특정하지 못합니다. 같은 다항식이라도 초기값, 입력 반사, 출력 반사, 최종 XOR 중 하나만 달라도 결과가 완전히 달라집니다. CRC-16/MODBUS와 CRC-16/ARC는 다항식이 같고 초기값만 다른데 결과는 아무 관계가 없어 보입니다. 데이터시트에서 네 가지 파라미터를 모두 확인하세요.

다항식이 0x8005인데 0xA001로 적힌 자료도 있습니다.

같은 다항식의 두 표기법입니다. 0x8005는 정방향, 0xA001은 비트를 뒤집은 역방향 표기입니다. 반사 구현에서는 역방향 상수를 쓰는 것이 계산에 편해서 코드에는 0xA001이 자주 등장합니다. 이 계산기는 정방향 표기를 받으므로 데이터시트에 역방향 값이 적혀 있다면 뒤집어서 넣어야 합니다.

반사가 무엇인가요?

각 바이트를 최하위 비트부터 처리할지 최상위 비트부터 처리할지의 선택입니다. UART처럼 하위 비트를 먼저 보내는 회선에서는 입력 반사가 자연스럽고, 그런 환경에서 자란 모델들이 반사를 씁니다. 출력 반사는 계산이 끝난 레지스터를 뒤집을지의 별도 선택이며, 둘을 따로 지정할 수 있습니다.

내 구현이 맞는지 어떻게 확인하나요?

문자열 "123456789"를 넣어 보세요. CRC 카탈로그가 모든 모델에 대해 이 입력의 결과를 검증값으로 제공하며, 이 계산기의 표준 모델도 그 값으로 확인했습니다. 구현한 코드가 같은 값을 내면 파라미터 해석이 맞은 것입니다.

CRC로 데이터를 보호할 수 있나요?

없습니다. CRC는 전송 중 우연히 생긴 오류를 잡기 위한 것이고, 의도적인 변조는 막지 못합니다. 원하는 CRC가 나오도록 데이터를 수정하는 것은 어렵지 않습니다. 변조를 막아야 한다면 CRC가 아니라 메시지 인증 코드가 필요합니다.