C 언어로 구현한 Bitwise CRC 계산 함수

2025년 11월 26일

2021년 12월, 방송신호 자동절체 제어기를 개발하기 위해 CRC(Cyclic Redundancy Check)계산에 대해 공부하며 만들어 본 CRC-5, CRC-7, CRC-8, CRC-10, CRC-16, CRC-32 계산하는 함수. 손으로 계산 하는 방법을 그대로 C 로 구현했다. 공부하느라 만든 것으로 당연히 효율성이나 속도따위는 고려대상이 아니었다.

당연히 기본 제공 라이브러리나, 더 머리 좋은 사람들이 공개한 효율적인 코드들도 존재한다. 하지만 일단, 내가 사용하는 놈이 뭐하는 놈인지와, 어떻게 동작하는지에 대해서는 알고 나서 사용해야 할 것이다.

CRC-5 계산함수

// SAPJIL CRC Calcurator by eqmaker
unsigned char CRC5_Generator(unsigned char *datastream, unsigned int numberofbyte, unsigned char poly)
{
	unsigned char rtn=0;
	for (unsigned int i=0; i<numberofbyte+1; i++)
	{
		for (char j= ((i==numberofbyte) ? 4 : 7); j>=0; j--)
		{
			if (rtn & 1<<4)
				{
					rtn = rtn << 1;
					rtn = (((i==numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
					rtn = rtn ^ poly;
				}
			else
				{
					rtn = rtn << 1;
					rtn = (((i==numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
				}
		}
	}
	return rtn & 0b00011111;
}

CRC-7 계산함수

// SAPJIL CRC Calcurator by eqmaker
unsigned char CRC7_Generator(unsigned char *datastream, unsigned int numberofbyte, unsigned char poly)
{
	unsigned char rtn=0;
	for (unsigned int i=0; i<numberofbyte+1; i++)
	{
		for (char j= ((i==numberofbyte) ? 6 : 7); j>=0; j--)
		{
			if (rtn & 1<<6)
				{
					rtn = rtn << 1;
					rtn = (((i==numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
					rtn = rtn ^ poly;
				}
			else
				{
					rtn = rtn << 1;
					rtn = (((i==numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
				}
		}
	}
	return rtn & 0b01111111;
}

CRC-8 계산함수

// SAPJIL CRC Calcurator by eqmaker
unsigned char CRC8_Generator(unsigned char *datastream, unsigned int numberofbyte, unsigned char poly)
{
	unsigned char rtn=0x00;
	for (unsigned int i=0; i<numberofbyte+1; i++)
	{
		for (char j=7; j>=0; j--)
		{
			if (rtn & 0x80)
				{
					rtn = rtn << 1;
					rtn = (((i==numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
					rtn = rtn ^ poly;
				}
			else
				{
					rtn = rtn << 1;
					rtn = (((i==numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
				}
		}
	}
	return (rtn);
}

CRC-10 계산함수

// SAPJIL CRC Calcurator by eqmaker
void CRC10_Generator(unsigned char *datastream, unsigned int numberofbyte, unsigned int poly)
{
	unsigned int rtn=0;
	for (unsigned int i=0; i<numberofbyte+2; i++)	//	8bit x 2 = 16bit 나머지 (중 10bit 사용)
	{
		for (char j=((i==numberofbyte+1) ? 1 : 7); j>=0; j--)		//	15-6 14-5 13-4 12-3 11-2 10-1 9-0
		{
			if (rtn & 1<<9)
				{
					rtn = rtn << 1;
					rtn = (((i>=numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
					rtn = rtn ^ poly;
				}
			else
				{
					rtn = rtn << 1;
					rtn = (((i>=numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
				}
		}
	}
	rtn = rtn & 0x03ff;
	printf("CRC10 : %04X\n", rtn);
}

CRC-16 계산함수

// SAPJIL CRC Calcurator by eqmaker
void CRC16_Generator(unsigned char *datastream, unsigned int numberofbyte, unsigned int poly)
{
	unsigned int rtn=0;
	for (unsigned int i=0; i<numberofbyte+2; i++)	//	8bit x 2 = 16bit 나머지
	{
		for (char j=7; j>=0; j--)
		{
			if (rtn & 0x8000)
				{
					rtn = rtn << 1;
					rtn = (((i>=numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
					rtn = rtn ^ poly;
				}
			else
				{
					rtn = rtn << 1;
					rtn = (((i>=numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
				}
		}
	}
	rtn = rtn & 0xffff;
	printf("CRC16 : %04X\n", rtn);
}

CRC-32 계산함수

// SAPJIL CRC Calcurator by eqmaker
void CRC32_Generator(unsigned char *datastream, unsigned int numberofbyte, unsigned int poly)
{
	unsigned int rtn=0;
	for (unsigned int i=0; i<numberofbyte+4; i++)	//	8bit x 4 = 32bit
	{
		for (char j=((i==numberofbyte+1) ? 7 : 7); j>=0; j--)	
		{
			if (rtn & 1<<31)
				{
					rtn = rtn << 1;
					rtn = (((i>=numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
					rtn = rtn ^ poly;
				}
			else
				{
					rtn = rtn << 1;
					rtn = (((i>=numberofbyte) ? 0 : datastream[i]) & (1<<j)) ? (rtn | 1) : rtn;
				}
		}
	}
	printf("CRC32 : %08X\n", rtn);
}

🔄 갱신 내역

  • 최초 게시
  • 블로그 이전
  • 블로그 이전 및 2차 수정