본문 바로가기
기타

CRC란?

by 코딩히어로 2022. 5. 24.
728x90

CRC 기본 개념


CRC는 Cyclic Redundancy Checking의 약자로 순환 중복검사라는 뜻입니다

순환 중복검사란 에러 검출 능력이 우수한 순회 부호의 일종으로 잘 정의된 수학적 구조를 가지며

부호화에 용이하고 매우 효율적인 복호화 기능을 가진다는 특징이 있습니다

 

CRC는 대부분 네트워크 등을 통한 데이터를 송수신할 때 전달된 데이터에 오류가

있는지 확인하기 위한 체크값을 결정하는 방식입니다

 

데이터를 전송하기 전에 주어진 데이터의 값에 따라 CRC값을 계산하여 데이터의 마지막 부분에 붙여 전송하고

데이터를 전달받으면 해당 데이터의 길이만큼의 값을통해 CRC를 계산합니다

 

CRC는 이진법 기반의 하드웨어에서 구현하기 좋고 데이터 전달 과정에서 발생하는

오류를 검출하는데 높은 신뢰성을 가집니다

 

 

CRC 개요


CRC는 다섯종류의 형식이 존재하며

CRC-16, CRC-32, CRC-64, CRC-128, CRC-256 등이 많이 사용되고 있습니다

CRC 계산법에 대해서는 위키백과에 잘 설명이 되어 있습니다

https://ko.wikipedia.org/wiki/%EC%88%9C%ED%99%98_%EC%A4%91%EB%B3%B5_%EA%B2%80%EC%82%AC

 

순환 중복 검사 - 위키백과, 우리 모두의 백과사전

순환 중복 검사(巡環重復檢査), CRC(cyclic redundancy check)는 네트워크 등을 통하여 데이터를 전송할 때 전송된 데이터에 오류가 있는지를 확인하기 위한 체크값을 결정하는 방식을 말한다. 데이터를

ko.wikipedia.org

하지만 위에서 설명된 CRC 계산법으로는 암호화라는 것보다는 해당 데이터가

오류가 있는지 정도를 확인하는 체크섬(Checksum) 느낌이 강합니다

 

제가 여러 센서나 서버 통신에서 마주했던 CRC 기법은

위키백과 마지막쪽에 구현되어 있는 CRC 테이블 기법을 많이 사용합니다

 

 

CRC 테이블 기법


 

먼저 CRC코드를 생성하고 분석할 CRC 테이블을 생성합니다

static unsigned char auchCRCHi[] = {
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
   0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
   0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40
};
static char auchCRCLo[] = {
   0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
   0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
   0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
   0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
   0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
   0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
   0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
   0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
   0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
   0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
   0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
   0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
   0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
   0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
   0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
   0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
   0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
   0x40
};

그다음 해당 테이블을 처리할 Function을 하나 생성합니다

crc_check라는 이름으로 인자로는 CRC코드를 위한 Data buffer와 Data buffer의 len을 설정합니다

int1 crc_check(unsigned char* arr,int len){

   unsigned char uchCRCHi = 0xFF; /* high byte of CRC initialized */
   unsigned char uchCRCLo = 0xFF; /* low byte of CRC initialized */
   unsigned uIndex; /* will index into CRC lookup table */

   while (len--) /* pass through message buffer */
   {
      uIndex = uchCRCHi ^ *arr++; /* calculate the CRC */
      uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
      uchCRCLo = auchCRCLo[uIndex];
   };
   
   test_hi = *arr++;
   test_lo = *arr++;
      
   if((uchCRCHi==test_hi)&&(uchCRCLo==test_lo)){
      return 1;
   }else{
      return 0;
   }
   
}

해당 Function에서는 CRC코드가 참일 경우 1을 리턴하고 거짓일 경우 0을 리턴합니다

제가 사용했던 센서는 CRC코드가 총 2byte로 데이터의 마지막 부분에 생성됩니다

int8 arr[] = {0x01,0x02,0x03,0x04,0x05,0x06,0xba,0xdd};

crc_check(arr,6);

위처럼 해당 배열의 앞의 요소 6개를 검사하여 마지막 두개의 CRC 값이 맞는지

확인하여 맞으면 1을 리턴 맞지 않으면 0을 리턴하여 해당 데이터를 판별합니다

728x90
반응형

'기타' 카테고리의 다른 글

이미지 용량 줄이는 사이트 정리  (4) 2022.06.08
RF란?  (2) 2022.06.07
Bluetooth RSSI 개념  (29) 2022.01.12
디자인 PSD파일이란?  (2) 2022.01.04
비트코인이란?  (6) 2022.01.03

댓글