常用的简单校验算法:校验和,异或校验,crc校验,LRC校验,补码求和,checksum
相关思路和源码来自网络,自己只是整理, 做笔记用。
并未完整完善正确归纳,只是个人理解初步做笔记记录。
在实现业务需求过程中,通常要用到相关一些校验算法,简单整理常用校验算法并做笔记:
常用校验算法简单说明:
1:校验和:按每个字节,计算累加和,
2:异或校验:定义初值,按每个字节异或,求结果。
3:CRC校验:已有很多的标准及计算方式,可以返回8字节,16字节,32字节的结果。
受益匪浅的文章:https://blog.csdn.net/u013073067/article/details/86621770
设置crc值和多项式码;依次遍历每个字节,与crc值进行异或;crc值取出最低位的值,并右移一位;如果最低位值位1,则于多项式码进行异或;循环直到8位结束。
crc查表思想:观察,内部有个循环,每次对一个字节(8位)的循环中,对crc码的数字是不变的,这里与多项式码相关,可以直接用数组代替这里的求值。(crc表与crc返回8/16/32位有关,与多项式码有关)
4:LRC校验:是不可靠的,先求和,再对结果取反+1
5:checksum:对checksum值归0,每16bit求和,不够16bit的高位补0,如果checksum溢出,则高16bit和低16bit相加进行处理(依次循环判断)。
测试demo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
unsigned char Check(const unsigned char *buf, int len)
{
int iSum = 0;
for (int i = 0;i < len;i++)
{
iSum += buf[i];
}
iSum %= 0x100;
return (unsigned char)iSum;
}
unsigned char CheckXor(const char *strData,int len)
{
char checksum = 0;
for (int i = 0;i < len;i++)
{
checksum = checksum ^ strData[i];
}
return (unsigned char)checksum;
}
unsigned short int CRC(const unsigned char *buf, int leng)
{
unsigned short int Reg,temp,Crccode,i,j;
Reg = 0xFFFF;
Crccode = 0xA001;
for ( i=0;i<leng;i++ )
{
Reg ^= *(buf+i);
for ( j=0;j<8;j++ )
{
temp=Reg&0x0001;
Reg=Reg>>1;
if( temp==0x0001 )
Reg^=Crccode;
}
}
return (Reg<<8 | Reg>>8);
}
unsigned char LRC(const unsigned char *auchMsg, unsigned short usDataLen)
{
unsigned char uchLRC=0;
while(usDataLen--)
{
uchLRC+=*auchMsg++;
}
return ((unsigned char)(-((char)uchLRC)));
}
unsigned char Check1(const unsigned char *buf, int len)
{
int iSum = 0;
for (int i = 0;i < len;i++)
{
iSum += buf[i];
}
iSum = 256 - iSum;
return (unsigned char)iSum;
}
uint32_t checksum(const void *buf, size_t len, uint32_t sum)
{
uintptr_t ptr = (uintptr_t)buf;
typedef uint16_t __attribute__((__may_alias__)) u16_p;
const u16_p *u16_buf = (const u16_p *)ptr;
while (len >= (sizeof(*u16_buf) * 4)) {
sum += u16_buf[0];
sum += u16_buf[1];
sum += u16_buf[2];
sum += u16_buf[3];
len -= sizeof(*u16_buf) * 4;
u16_buf += 4;
}
while (len >= sizeof(*u16_buf)) {
sum += *u16_buf;
len -= sizeof(*u16_buf);
u16_buf += 1;
}
if (len == 1)
sum += *((const uint8_t *)u16_buf);
return sum;
}
int main(int argc, char* argv[])
{
const char * src_data = "abcdefghi";
printf("check %02x \n", Check((const unsigned char*)src_data, strlen(src_data)));
printf("CheckXor %02x \n", CheckXor((const char*)src_data, strlen(src_data)));
printf("CRC : %02x \n", CRC((const unsigned char*)src_data, strlen(src_data)));
printf("LRC: : %02x \n", LRC((const unsigned char*)src_data, strlen(src_data)));
printf("Check1: %02x \n", Check1((const unsigned char*)src_data, strlen(src_data)));
printf("sizeof(char*) = %lu \n", sizeof(char*));
unsigned int cksum = checksum((const void*)src_data, strlen(src_data), 0);
cksum = (cksum == 0xffff) ? cksum : (uint16_t)~cksum;
printf("checksum : %02x \n", cksum);
const char* data = "2|4|12312|119|{\"InternalFleetNum\":\"12345\",\"CoordX\":1178263,\"CoordY\":2083177,\"Heading\":121.7,\"LocationCode\":\"AVB\",\"RequestId\":1234567}";
printf("data is [%s] \n",data);
char* buff = NULL;
buff = (char*)malloc(strlen(data) +2);
memset(buff, 0, strlen(data) +2);
memcpy(buff, data, strlen(data));
printf("buff is [%s] \n",buff);
unsigned char check_xor = CheckXor((const char*)data, strlen(data));
printf("check_xor = [%c] \n", check_xor);
memcpy(buff+strlen(data), (char*)&check_xor, 1);
printf("buff adn check_xor is [%s] \n",buff);
unsigned char check_xor1 = CheckXor(buff, strlen(buff)-1);
printf("check_xor1 is [%c] \n", check_xor1);
printf("data check_xor is [%c] \n", *(buff+strlen(buff)-1));
if(check_xor1 == *(buff+strlen(buff)-1))
{
printf("data is success ! \n");
}else
{
printf("data is error! \n");
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)