CRC8校验

#include <stdio.h>
#include <string.h>

typedef struct
{
	unsigned char poly;//多项式X8+X2+X+1/X8+X5+X4+1
	unsigned char InitValue;//算法开始时寄存器(crc)的初始化预置值
	unsigned char xor;//计算结果与此参数异或后得到最终的CRC值
	unsigned char InputReverse; //待测数据的每个字节是否按位反转,True或False
	unsigned char OutputReverse;////在计算后之后,异或输出之前,整个数据是否按位反转,True或False
}CRC_8;

CRC_8 tpye = 
{
	.poly = 0x31,         
	.InitValue = 0x00,   
	.xor = 0x00,		 
	.InputReverse = 1,   
	.OutputReverse = 1,  
};

unsigned char reverse8(unsigned char data)
{
    unsigned char i;
    unsigned char temp=0;
    for(i=0;i<8;i++)	//字节反转
        temp |= ((data>>i) & 0x01)<<(7-i);
    return temp;

}
unsigned char crc8(unsigned char *addr, int num,CRC_8 type)  
{  
    unsigned char data;
    unsigned char crc = type.InitValue;                   //初始值
    int i;  
    for (; num > 0; num--)               
    {  
        data = *addr++;
        if(type.InputReverse == 1)
        data = reverse8(data);                 //字节反转
        crc = crc ^ data ;                     //与crc初始值异或 
        for (i = 0; i < 8; i++)                //循环8位 
        {  
            if (crc & 0x80)                    //左移移出的位为1,左移后与多项式异或
                crc = (crc << 1) ^ type.poly;    
            else                               //否则直接左移
                crc <<= 1;                  
        }
    }
    if(type.OutputReverse == 1)             //满足条件,反转
        crc = reverse8(crc);
    crc = crc^type.xor;                        //最后返与结果异或值异或
    return(crc);                               //返回最终校验值
}



unsigned char crc_high_first(unsigned char *ptr, unsigned char len)
{
    unsigned char i; 
    unsigned char crc=0x00; 	/* 计算的初始crc值 */ 
 
    while(len--)
    {
        crc ^= (*ptr)++;  		/* 每次先与需要计算的数据异或,计算完指向下一数据 */  
        for (i=8; i>0; --i)     /* 下面这段计算过程与计算一个字节crc一样 */  
        { 
            if (crc & 0x80)
                crc = (crc << 1) ^ 0x31;
            else
				crc = (crc << 1);
        }
    }
 
    return (crc); 
}


int StringToHex(char *str, int len, unsigned char *strhex)
{
	unsigned int i,cnt=0;
	char tmp = 0;
	
	if (len%2)
	{
		return -1;
	}
	
	for (i = 0; i < len; i++)  //循环判断当前字符是数字还是小写字符还是大写字母
	{
		if (i%2)
		{
			strhex[cnt] = tmp;
			if ((str[i] >= '0') && (str[i] <= '9')) //当前字符为数字0~9时
				tmp = (str[i] - '0');
			else if ((str[i] >= 'A') && (str[i] <= 'F')) //当前字符为大写字母A~Z时
				tmp = ((str[i] - 'A') + 10);
			else if ((str[i] >= 'f') && (str[i] <= 'f')) //当前字符为小写字母a~z时
				tmp = ((str[i] - 'a') + 10);
			strhex[cnt] += tmp;
			cnt++;
		}
		else
		{
			if ((str[i] >= '0') && (str[i] <= '9')) //当前字符为数字0~9时
				tmp = 16*(str[i] - '0');
			else if ((str[i] >= 'A') && (str[i] <= 'F')) //当前字符为大写字母A~Z时
				tmp = 16*((str[i] - 'A') + 10);
			else if ((str[i] >= 'a') && (str[i] <= 'f')) //当前字符为小写字母a~z时
				tmp = 16*((str[i] - 'a') + 10);
		}
	}
	return cnt;
}
int main(int argc, char*argv[])
{
	int cnt;
	unsigned char strhex[1024] = {0};
	if (2 > argc)
	{
		printf("##please input the hexstring##\n");
		return -1;
	}
	if (1024 < strlen(argv[1]))
	{
		printf("##please input the hexstring len less 1024 now len = %d##\n", (int)strlen(argv[1]));
		return -1;
	}
    cnt = StringToHex(argv[1], strlen(argv[1]), strhex);
	if (-1 == cnt)
	{
		printf("##stringtohex error##\n");
		return -1;
	}
	printf("##stringtohex ok##\n");
	printf("##crc = 0x%02x##\n", crc8(strhex, cnt, tpye));
	return 0;
}
发布了33 篇原创文章 · 获赞 7 · 访问量 8340

猜你喜欢

转载自blog.csdn.net/muchong123/article/details/103500693