노트 / 자료구조와 알고리즘
CRC와 체크섬: 깨진 데이터 알아내기
통신 중 비트가 뒤집혔는지 확인하는 계산. 단순 합 체크섬과 CRC의 차이, 그리고 구현 방법을 정리했습니다.
노이즈가 있는 선 위의 데이터는 언제든 비트 하나가 바뀔 수 있습니다. 받는 쪽이 이를 알아채려면 보내는 쪽이 데이터로 계산한 확인값을 함께 보내고, 받는 쪽이 같은 계산을 해서 비교합니다.
체크섬
모든 바이트를 더하거나 XOR합니다. 구현은 한 줄이지만, 두 바이트가 서로 반대로 바뀌거나 순서가 바뀌면 알아채지 못합니다.
CRC
데이터를 하나의 긴 2진수로 보고 정해진 다항식으로 나눈 나머지를 확인값으로 씁니다. 연속된 비트 오류를 아주 잘 잡아내서 CAN, Modbus, 이더넷, USB가 모두 CRC를 씁니다.
uint16_t crc16_modbus(const uint8_t *p, size_t n) {
uint16_t crc = 0xFFFF;
while (n--) {
crc ^= *p++;
for (int i = 0; i < 8; i++)
crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
}
return crc;
}
구현 선택
| 방식 | 속도 | 메모리 |
|---|---|---|
| 비트 단위 루프 | 느림 | 거의 없음 |
| 256칸 표 | 빠름 | 512바이트(CRC16) |
| 하드웨어 CRC 유닛 | 가장 빠름 | 없음 |
CRC 종류마다 다항식, 초기값, 비트 반전 여부가 다르니 상대 장비의 사양서에 적힌 값을 그대로 맞추고, 알려진 테스트 문자열 "123456789"의 결과로 검증합니다.