본문 바로가기
개발/통신

crc16 source code

by 즐기며 2025. 9. 8.

 

 

crc 16 소스 코드 입니다.

 

1. CRC-16 다항식 을 선택 합니다. 
// 0x8005 for CRC16-IBM, == x16 + x15 + x2 + x0 == 1 1000 0000 0000 0101
// 0x1021 for CRC16-CCITT == x16 + x12 + x5 + x0 == 1 0001 0000 0010 0001
#define POLYNOMIAL 0x8005
#define TABLE_SIZE 256

 

2. table 방식과 직접 계산 방식을 하였는데, 테이블은 256 개로 합니다.

// CRC-16 lookup 테이블
uint16_t crc16_table[TABLE_SIZE];

// CRC-16 테이블 생성 함수
void generate_crc16_table(void) {
	int i,j;
	uint16_t crc;
    for (i = 0; i < TABLE_SIZE; i++) {
        crc = i << 8; // 상위 8비트를 i로 설정
        for (j = 0; j < 8; j++) {
            if (crc & 0x8000) { // 최상위 비트가 1이면
                crc = (crc << 1) ^ POLYNOMIAL; // 왼쪽 시프트 후 다항식과 XOR
            } else {
                crc <<= 1; // 왼쪽 시프트
            }
        }
        crc16_table[i] = crc;
    }
}

 

 

3. table 이용 하여 crc16 계산

uint16_t crc16_useTable(unsigned char* pD, uint16_t len) {
    uint16_t i, j;
	uint16_t crc_accum = 0;

    for (j = 0; j < len; j++)
    {
        i = ((uint16_t)(crc_accum >> 8) ^ pD[j]) & 0xFF;
        crc_accum = (crc_accum << 8) ^ crc16_table[i];
    }

    return crc_accum;
}

 

4. 직접 crc 계산

uint16_t crc16_Direct(const uint8_t* data, int length) {
	uint16_t crc = 0x0000;

	while (length--) {
		crc ^= (*data++) << 8;

		for (int i = 0; i < 8; ++i) {
			if (crc & 0x8000)
				crc = (crc << 1) ^ POLYNOMIAL;
			else
				crc <<= 1;
		}
	}
	return crc;
}

 

 

5. 결과 보기

int _tmain(int argc, _TCHAR* argv[])
{
	uint8_t d[] = { 0x41, 0x42, 0x43, 0x44 };	// data = ABCD
	int i;

    generate_crc16_table();		// make table
    print_crc16_table();		// show table

	printf(" Data:");  for(i=0; i<sizeof(d); i++ ) printf(" 0x%02X", d[i]);	// show input data
	printf(" >>>Table:  0x%04X,   ", crc16_useTable(d, sizeof(d)));			// result
	printf(" >>>Direct: 0x%04X\n", crc16_Direct(d, sizeof(d)));				// result 
	return 0;
}

여기서는 간단히 결과만 보는 코드 인데, 첨부 소스는 변환하는데 걸리는 시간 계산 하기 위하여 조금 바꾸 었읍니다.

Look Up  Table 쓰는 방식이, 직접 계산 하는 방식 보다 반도 안걸리 네요.

 

6. crc16-ibm table

 Polynomial = 0x8005,  crc16-ibm table
 uint16_t crc16_table[256] = {
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
};

 

7. crc16-ccitt table

 Polynomial = 0x1021,    crc16-ccitt table
uint16_t crc16_table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};

 

 

8. CRC16-CCITT 로  문자 A ( 0x41) 때와   ABCD 때 CRC 구하기 

보낼 데이터 : 0x41 의 CRC 직접 구해 보기

0x41 뒤에 16 bit 0 추가 
	= 0x41 00 00
    = 0100 0001 0000 0000 0000 0000 을
crc16 ccitt 0x1021 
	= 1 0001 0000 0010 0001 로 나눈다

   ______________________________
  | 0100 0001 0000 0000 0000 0000
     100 0100 0000 1000 01
     ----------------------------
          101 0000 1000 0100 000
          100 0100 0000 1000 010
          ----------------------
            1 0100 1000 1100 0100
            1 0001 0000 0010 0001
            ---------------------
              0101 1000 1110 0101 == 0x58E5  <= CRC
              
 마찬가지로 보낼 데이타가 ABCD 이면
 0x41424344 뒤에 16 bit 0 추가 
	= 0x41 42 43 44 00 00
    = 0100 0001 0100 0010 0100 0011 0100 0100 0000 0000 0000 0000 을
crc16 ccitt 0x1021
	= 1 0001 0000 0010 0001 로 나눈다
CRC 는 0x3B3A 로 나온다.

 

 

9. 전체 소스

crc16.zip
0.00MB

 

 

 

 

수고 하셨읍니다.