求教C语言编写的CRC16的校验程序

求教C语言编写的CRC16的校验程序,第1张

unsigned short crc_dsp(unsigned short reg, unsigned char data_crc)

//reg为crc寄存器, data_crc为将要处理的8bit数据流

{

unsigned short msb; //crc寄存器将移出的最高1bit

unsigned short data;

unsigned short gx = 0x8005, i = 0; //i为左移次数, gx为生成多项式

data = (unsigned short)data_crc;

data = data << 8;

reg = reg ^ data;

do

{

msb = reg & 0x8000;

reg = reg << 1;

if(msb == 0x8000)

{

reg = reg ^ gx;

}

i++;

}

while(i < 8);

return (reg);

}

long int GenerateChecksumCRC24_D32(unsigned long ulNumValues,unsigned long pulData)

{

unsigned long i,ulData,lfsr = 0xFFFFFF;

for (i= 0x0; i < ulNumValues;i++)

{

ulData = pulData[i];

lfsr = CRC24_D32(lfsr,ulData);

}

return lfsr;

}

static unsigned long CRC24_D32(const unsigned long old_CRC, const unsigned long Data)

{

unsigned long D [32];

unsigned long C [24];

unsigned long NewCRC [24];

unsigned long ulCRC24_D32;

unsigned long int f, tmp;

unsigned long int bit_mask = 0x000001;

tmp = 0x000000;

// Convert previous CRC value to binary

bit_mask = 0x000001;

for (f = 0; f <= 23; f++)

{

C[f] = (old_CRC & bit_mask) >> f;

bit_mask = bit_mask << 1;

}

// Convert data to binary

bit_mask = 0x000001;

for (f = 0; f <= 31; f++)

{

D[f] = (Data & bit_mask) >> f;

bit_mask = bit_mask << 1;

}

// Calculate new LFSR value

NewCRC[0] = D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[27] ^ D[26] ^ D[25] ^

D[24] ^ D[23] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^

D[12] ^ D[11] ^ D[10] ^ D[9] ^ D[8] ^ D[7] ^ D[6] ^

D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^

C[2] ^ C[3] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ C[8] ^ C[9] ^

C[15] ^ C[16] ^ C[17] ^ C[18] ^ C[19] ^ C[20] ^ C[21] ^

C[22] ^ C[23];

NewCRC[1] = D[23] ^ D[18] ^ D[0] ^ C[10] ^ C[15];

NewCRC[2] = D[24] ^ D[19] ^ D[1] ^ C[11] ^ C[16];

NewCRC[3] = D[25] ^ D[20] ^ D[2] ^ C[12] ^ C[17];

NewCRC[4] = D[26] ^ D[21] ^ D[3] ^ C[13] ^ C[18];

NewCRC[5] = D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[26] ^ D[25] ^ D[24] ^

D[23] ^ D[22] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^

D[12] ^ D[11] ^ D[10] ^ D[9] ^ D[8] ^ D[7] ^ D[6] ^

D[5] ^ D[3] ^ D[2] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^ C[2] ^

C[3] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ C[8] ^ C[9] ^ C[14] ^

C[15] ^ C[16] ^ C[17] ^ C[18] ^ C[20] ^ C[21] ^ C[22] ^

C[23];

LFSR代码示例

签名是一个多项式为x24+ x23+ x6

+ x5

+x+1的24位CRC。初始值为0xFFFFFF。

AN-1160

Rev A | Page 7 of 8

NewCRC[6] = D[28] ^ D[18] ^ D[5] ^ D[0] ^ C[10] ^ C[20];

NewCRC[7] = D[29] ^ D[19] ^ D[6] ^ D[1] ^ C[11] ^ C[21];

NewCRC[8] = D[30] ^ D[20] ^ D[7] ^ D[2] ^ C[12] ^ C[22];

NewCRC[9] = D[31] ^ D[21] ^ D[8] ^ D[3] ^ C[0] ^ C[13] ^ C[23];

NewCRC[10] = D[22] ^ D[9] ^ D[4] ^ C[1] ^ C[14];

NewCRC[11] = D[23] ^ D[10] ^ D[5] ^ C[2] ^ C[15];

NewCRC[12] = D[24] ^ D[11] ^ D[6] ^ C[3] ^ C[16];

NewCRC[13] = D[25] ^ D[12] ^ D[7] ^ C[4] ^ C[17];

NewCRC[14] = D[26] ^ D[13] ^ D[8] ^ C[0] ^ C[5] ^ C[18];

NewCRC[15] = D[27] ^ D[14] ^ D[9] ^ C[1] ^ C[6] ^ C[19];

NewCRC[16] = D[28] ^ D[15] ^ D[10] ^ C[2] ^ C[7] ^ C[20];

NewCRC[17] = D[29] ^ D[16] ^ D[11] ^ C[3] ^ C[8] ^ C[21];

NewCRC[18] = D[30] ^ D[17] ^ D[12] ^ C[4] ^ C[9] ^ C[22];

NewCRC[19] = D[31] ^ D[18] ^ D[13] ^ C[5] ^ C[10] ^ C[23];

NewCRC[20] = D[19] ^ D[14] ^ C[6] ^ C[11];

NewCRC[21] = D[20] ^ D[15] ^ C[7] ^ C[12];

NewCRC[22] = D[21] ^ D[16] ^ C[8] ^ C[13];

NewCRC[23] = D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[27] ^ D[26] ^ D[25] ^

D[24] ^ D[23] ^ D[22] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^

D[12] ^ D[11] ^ D[10] ^ D[9] ^ D[8] ^ D[7] ^ D[6] ^

D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^

C[2] ^ C[3] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ C[8] ^ C[14] ^

C[15] ^ C[16] ^ C[17] ^ C[18] ^ C[19] ^ C[20] ^ C[21] ^

C[22] ^ C[23];

ulCRC24_D32 = 0;

// LFSR value from binary to hex

bit_mask = 0x000001;

for (f = 0; f <= 23; f++)

{

ulCRC24_D32 = ulCRC24_D32 + NewCRC[f] bit_mask;

bit_mask = bit_mask << 1;

}

return(ulCRC24_D32 & 0x00FFFFFF);

}

给你个参考:

#include<stdioh>

#include<conioh> //用getch()函数时要的文件头

#include<stringh>

#define USER "admin"

#define PWD "admin"

void main()

{

char user[20], pwd[16], ch;

int count=0, i=0;

while(count<3) //3次机会输入正确密码

{

printf("user name:");

gets(user);

printf("password:");

while((ch=getch())!=13&&i<16) //将输入的密码转换成字符

{

putchar('');

pwd[i]=ch;

i++;

}

pwd[i]=0;

if(!strcmp(USER,user)&&!strcmp(PWD,pwd))

break;

else

printf("\nincorrect user name or password!\n");

count++;

}

printf("\nlogin successful!\n");

}

这个应该是ICMP协议的checksum

short checksum(ushort buffer int size) //这里定义的是指针吧 unsigned short buffer,为ICMP的协议类型ICMP_ECHO值为8,size为发送封包大小,因为ip header占20字节,所以你发送一个最短的64bytes的数据包,size为44

unsigned long cksum = 0 //32位系统占4个字节,32个位,后面有低位和高位运算

while(size> 1)//为什么size要大于1

{

cksum += buffer++ //这个应该是cksum += buffer++,指针偏移

size -= sizeof(ushort) //size -= 2,判断循环执行次数

}

if(size)

{

cksum += (uchar)buffer //如果packet为奇数,例如65,那个再加一次buffer

}

cksum = (cksum> > 16) + (cksum& 0xffff) //将高16bit与低16bit相加(&与运算把最高位去除 得到他的后16位)(整数移位后会只取整数部分

cksum += (cksum> > 16) //将进位到高位的16bit与低16bit 再相加,为什么这里不进行与运算????

return (ushort)(~cksum) //~取反(转换成短整型)

}

short checksum(ushort buffer int size)//buffer表示需要进行校验和运算的内存开始地址 size表示这块内存区的长度

{

unsigned long cksum = 0 //由于是16位校验和最终要加上溢出位 所以要用long

while(size> 1)//因为ushort一次加上2个字节 如果结尾还剩一个字节的时候再按照这种方式加就会导致校验错误

{

cksum += buffer++ //校验和的原理就是 ,全部数据加起来, 再取反。 这样传输过程中如果出现数据错误 ,那么加起来的值就不一样。通过对比这个值来验证数据是否正确

size -= sizeof(ushort) //加一次后 size减ushort的长度(一般是2)

}

if(size)

{

cksum += (uchar)buffer//在只剩一个字节的 时候需要强制转换为uchar再进行加法运算

}

cksum = (cksum> > 16) + (cksum& 0xffff) //将溢出的部分相加

cksum += (cksum> > 16) //再次跟溢出的部分相加

return (ushort)(~cksum) //~取反(转换成短整型)

}

整个过程就是 将一个ushort内的数据全部加起来

然后将溢出部分加起来(由于校验值只是2个字节(ushort)所以要将溢出的部分也加进来)

溢出部分加的时候有可能再溢出一次(就是当校验值为0xffff时候 +上溢出的值就有可能再溢出一次

所以需要重新加一次

最后将得到的校验和取反转换为ushort型

以上就是关于求教C语言编写的CRC16的校验程序全部的内容,包括:求教C语言编写的CRC16的校验程序、跪求24位CRC校验的C语言程序,生成多项式g(x)=x^24+x^23+x^6+x^5+x+1、C语言中密码校验怎么做等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10217470.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存