CRC校验代码看不懂,请求高手支招。目前我看不懂的一篇CRC校验文章和一套逆序CRC校验。 80C

#各位大神,我看不懂这篇文章还有一段逆序CRC代码。请各位大神帮帮忙:

1、文章(链接地址:https://wenku.baidu.com/view/9f7b55876f1aff00bed51ec0.html)

下面为不完全版
CRC(Cyclic Redundancy Check)校验应用较为广泛,以前为了处理简单,在程序中大多数采用LRC(Longitudinal Redundancy Check)校验,LRC校验很好理解,编程实现简单。用了一天时间研究了CRC的C语言实现,理解和掌握了基本原理和C语言编程。结合自己的理解简单写下来。
1、CRC简介
CRC检验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个检验码r位(就是CRC码),附在信息后面,构成一个新的二进制码序列数共(k+r)位,最后发送出去。接收端根据同样的规则校验,以确定传送中是否出错。接收端有两种处理方式:1、计算k位序列的CRC码,与接收到的CRC比较,一致则接收正确。2、计算整个k+r位的CRC码,若为0,则接收正确。
CRC码有多种检验位数,8位、16位、32位等,原理相同。16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(即乘以2的16次方后),除以一个多项式,最后所得到的余数就是CRC码。
求CRC码所采用的是模2运算法则,即多项式除法中采用不带借位的减法运算,运算等同于异或运算。这一点要仔细理解,是编程的基础。
CRC-16: (美国二进制同步系统中采用) G(X) = X16 + X15 + X2 + 1
CRC-CCITT: (由欧洲CCITT推荐) G(X) = X16 + X12 + X5 + 1
CRC-32: G(X) = X32 + X26 + X23 + X22 + X16 +X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + 1
2、按位计算CRC
采用CRC-CCITT多项式,多项式为0x11021,C语言编程时,参与计算为0x1021,这个地方得深入思考才能体会其中的奥妙,分享一下我的思路:当按位计算CRC时,例如计算二进制序列为1001 1010 1010 1111时,将二进制序列数左移16位,即为1001 1010 1010 1111 (0000 0000 0000 0000),实际上该二进制序列可拆分为1000 0000 0000 0000 (0000 0000 0000 0000) + 000 0000 0000 0000 (0000 0000 0000 0000) + 00 0000 0000 0000 (0000 0000 0000 0000) + 1 0000 0000 0000 (0000 0000 0000 0000) + ……
现在开始分析运算:
对第一个二进制分序列求余数,竖式除法即为0x10000 ^ 0x11021运算,后面的0位保留;
接着对第二个二进制分序列求余数,将第一步运算的余数*2后再和第二个二进制分序列一起对0x11021求余,这一步理解应该没什么问题。如果该分序列为0,无需计算。
对其余的二进制序列求余与上面两步相同。
计算到最后一位时即为整个二进制序列的余数,即为CRC校验码。
该计算方法相当于对每一位计算,运算过程很容易理解,所占内存少,缺点是一位一位计算比较耗时。
下面给出C语言实现方法:
复制代码 代码如下:

第一段代码

unsigned char test[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
void main( void )
{
unsigned long temp = 0;
unsigned int crc;
unsigned char i;
unsigned char *ptr = test;
while( len-- ) {
for(i = 0x80; i != 0; i = i >> 1) {
temp = temp * 2;
if((temp & 0x10000) != 0)
temp = temp ^ 0x11021;

     if((*ptr & i) != 0) 
        temp = temp ^ (0x10000 ^ 0x11021);
 }
ptr++;

}
crc = temp;
printf("0x%x ",crc);
}

上面的程序根据运算分析而来,很容易理解。为了节约内存空间,我们对程序作进一步的简化。分析可知,当二进制序列中上一位计算的余数第15bit位为1时,即( 上一位计算的余数 & 0x8000) != 0,计算本位时,上一位余数 * 2后可对0x11021作求余运算,然后再加上本位计算所得余数。这个很好理解,也就是说,打个比方,把它看作简单的除法,计算上一位时的余数乘以2后,如果比较大可以当被除数,就再去除除数求余。有一点和普通除法不同的是,因为多项式除法中采用不带借位的减法运算,所以0x10000也可以被0x11021除,余数并非为0x10000,而是0x1021。这个自己动手算一下就知道了。余数之和也是不带进位的加法运算,即异或。最后还强调一点,因为二进制序列是左移16位后参与运算的,所以,一直算到序列的最后一位也是可以被除的,这点大家要明白。下面给出简化后的C语言实现。
复制代码 代码如下:

第二段代码

unsigned char test[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
void main( void )
{
unsigned int crc = 0;
unsigned char i;
unsigned char *ptr = test;
while( len-- ) {
for(i = 0x80; i != 0; i = i >> 1) {
if((crc & 0x8000) != 0) {
crc = crc << 1;
crc = crc ^ 0x1021;
}
else {
crc = crc << 1;
}
if((*ptr & i) != 0) {
crc = crc ^ 0x1021;
}
}
ptr++;
}
printf("0x%x ",crc);
}

上面这段程序网上较为常见,但冇得详细的解释。通过我上面的详细分析,如果对此段程序理解还有困难,可以对比一下没简化之前的程序,细细品味一哈,还是比较容易理解的。要是还理解不了,还是从头再看下,我码这么多字容易吗。。。。。
按位计算CRC代码比较简单,所占内存少,但要一位一位去计算,下面再介绍一种按字节查表快速计算CRC的方法。
3、按字节计算CRC
有了上面按位计算的知识,理解这个就是小case了。还是举前面的例子:当字节计算CRC时,例如计算二进制序列为1001 1010 1010 1111时,即0x9a9f时,将二进制序列数左移16位,即为0x9a9f(0 0 0 0),实际上该二进制序列可拆分为0x9a00(0 0 0 0) + 0x009f(0 0 0 0),分析计算时和上面的步骤一样,唯一不同的是计算中上一步的余数CRC要乘以2的八次方参与下一步的运算,这个应该好理解撒。为了简化编程,将计算中的CRC拆成高八位和低八位的形式,高八位的值直接与本位值相加求余,低八位的值乘以2的八次方后作为余数和计算得的余数相加。为了提高计算速度,我们把8位二进制序列数的CRC全部计算出来,放在一个表中,采用查表法可大大提高计算速度。
表是怎么得到的呢?当然是计算出来的,下面的程序给出了多项式是0x11021的计算程序。
复制代码 代码如下:

第三段代码

void main( void )
{
unsigned int crc = 0;
unsigned char i;
unsigned int j;
for(j = 0; j < 256; j++) {
crc = 0;
for(i = 0x80; i != 0; i = i >> 1) {
if((crc & 0x8000) != 0) {
crc = crc << 1;
crc = crc ^ 0x1021;
}
else {
crc = crc << 1;
}
if((j & i) != 0) {
crc = crc ^ 0x1021;
}
}
printf("0x");
if(crc < 0x10) {
printf("000");
}
else if(crc < 0x100) {
printf("00");
}
else if(crc < 0x1000) {
printf("0");
}
printf("%x, ",crc);
}
}

如果你不是使用的0x11021多项式,只需把程序中0x1021换成其他的就可以了。后面的几个printf语句为了控制使生成的表比较整齐,如果无所谓,可直接用printf("0x%x, ",crc);代替。生成的表如下:
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,
好了,我们来写按字节计算的源程序:

第六段代码(CRC逆序校验代码)

uint8 xCal_crc(uint8 *ptr,uint32 len)
{
uint8 crc;
uint8 i;
uint32 lenBak = len;
uint8 *ptrBak = ptr;
uint32 Debuglen = lenBak;
uint8 *Debugptr = ptrBak;
char CrcSendBuf[100] = {0};
crc = 0;
while(len--)
{
crc ^= *ptr++;
memset(CrcSendBuf, 0, 100);
sprintf(CrcSendBuf, "head->crc = %02x \r\n", crc);

UartSendString(CrcSendBuf, strlen(CrcSendBuf));
for(i = 0;i < 8;i++)
{
if(crc & 0x01)
{
crc = (crc >> 1) ^ 0x8C;
}
else
{
crc >>= 1;
}
}
}
return crc;
}

4个回答

异或就是异为1,同为0,所有的位运算都是为了对位进行操作,只要能得到你想要的数,怎么操作不重要。

gemmax
gemmax 回复u013550528: 理解你的探索精神,但作者的习惯意图可能有所不同,理解知识点即可,不用纠结这个。把精力放在更值得钻研的地方吧。
大约 2 年之前 回复
u013550528
陈川川 回复gemmax: 有括号加在后面,作者的用意是什么啊?
大约 2 年之前 回复
u013550528
陈川川 回复gemmax: 这样啊,但他这样整理可读性太差了吧?temp = temp ^ (0x10000 ^ 0x11021)与temp = temp ^ 0x1021效果相同这个我知道,我其实纠结的是为什么有括号加在后面
大约 2 年之前 回复
u013550528
陈川川 这样啊,但他这样整理可读性太差了吧?temp = temp ^ (0x10000 ^ 0x11021)与temp = temp ^ 0x1021效果相同这个我知道,我其实纠结的是为什么有括号加在后面
大约 2 年之前 回复
gemmax
gemmax 回复u013550528: 此处是指举的例子还是上面的问题? 我觉得,言尽如此了,如果对可读性不理解,可以百度更好的例子帮助你理解。如果是上面的问题,你可以对知识点进行梳理,看看。当然,可读性只是一个推断,建立在temp = temp ^ (0x10000 ^ 0x11021)与temp = temp ^ 0x1021效果相同的基础上。
大约 2 年之前 回复
u013550528
陈川川 回复gemmax: 在此处它的可读性从哪体现出来啊?
大约 2 年之前 回复
gemmax
gemmax 回复陈川川: 尴尬,是Byte 和KB
大约 2 年之前 回复
gemmax
gemmax 回复陈川川: 举的例子可能不太好,但觉得这样直观些,大多少指倍数
大约 2 年之前 回复
gemmax
gemmax 回复陈川川: 比方说,文件1容量大小为a,单位bit,文件2容量2kb。求1文件比2文件大多少,可以把a/1024转化成kb,再除以2.所以写成 a/1024/2比a/2048可读性好。
大约 2 年之前 回复
u013550528
陈川川 回复陈川川: 怎么便于理解了,我搞不懂,请您赐教下哈
大约 2 年之前 回复
gemmax
gemmax 回复陈川川: 还是说,也可以这么写,但他为什么没有这么写? 如果是后者,那么就是为了可读性,便于理解。
大约 2 年之前 回复
u013550528
陈川川 回复gemmax: 我是问他为什么这么写temp = temp ^ (0x10000 ^ 0x11021)
大约 2 年之前 回复
gemmax
gemmax 回复陈川川: 你是问写成temp ^ 0x1021就结果不正确?还是说,也可以这么写,但他为什么没有这么写? 如果是后者,那么就是为了可读性,便于理解。如果是前者,我也很好奇,怎么会发生这种情况。提问内容太多,看起来好恐怖,没有看,不好意思哈。
大约 2 年之前 回复
gemmax
gemmax 回复gemmax: 应该说,相同的位数都为1,纠正一下。
大约 2 年之前 回复
gemmax
gemmax 回复陈川川: 我没看上面的代码,但直接解释这句的话:如果ptr指向的值与i的与操作的结果不为0,即值与i对应位数存在相同的数,则temp的值等于原temp的值与十进制数4129(即16进制0x1021)的异或。
大约 2 年之前 回复
u013550528
陈川川 但是这里的异或有模二除法、模加、模减的用法,if((*ptr & i) != 0) temp = temp ^ (0x10000 ^ 0x11021)这句他是怎么使用异或的我真的不太清楚,麻烦看一下
大约 2 年之前 回复

1 & 1 = 1 ; 1 & 0 = 0; 1 | 0 = 1; 0 | 0 = 0; 1异或0 = 1; 1异或1= 0; 0异或0 = 0;

u013550528
陈川川 这个,我也知道,但是能否解释一下if((*ptr & i) != 0) temp = temp ^ (0x10000 ^ 0x11021)这句啊
大约 2 年之前 回复

您直接用查表法应该就可以

u013550528
陈川川 我想先了解位运算先
大约 2 年之前 回复
u013550528
陈川川 我想了解清楚这个
大约 2 年之前 回复

我觉得你是对位运算不熟悉,好好练练位运算。

u013550528
陈川川 我知道是怎么算的,但我不知道为什么那个语句写成这样
大约 2 年之前 回复
u013550528
陈川川 你能否帮我解读下为什么写的是这句话? temp = temp ^ (0x10000 ^ 0x11021);
大约 2 年之前 回复
Moluth
Moluth 回复陈川川: 你自己按照上面的方法算一下,就对大致流程明白了。然后再看代码,代码有部分使用位运算提高性能的,从局部看可能不好理解。但是还是围绕着这个运算的,你要自己先明白怎么计算,再读代码就容易多了。
大约 2 年之前 回复
Moluth
Moluth 回复陈川川: 你要是实在不知道怎么算,给你个参考资料:https://pan.baidu.com/s/1rEmvLRiYG5MmmUSzzOXBYw 里面是我大学计算机网络课本,书的页码74。pdf的页码84,有怎么计算crc
大约 2 年之前 回复
Moluth
Moluth 回复陈川川: 下面大家都给你回复了异或怎么算了,实在不懂程序每一步都干了什么,那就每一步以二进制输出结果,看看数据发生了什么变化。仔细观察,你一定可以明白的。
大约 2 年之前 回复
u013550528
陈川川 异或运算我不太熟
大约 2 年之前 回复
u013550528
陈川川 我懂位运算但对疑惑运算不是太懂,比如if((*ptr & i) != 0) temp = temp ^ (0x10000 ^ 0x11021);这句为什么是这样写?
大约 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
802.11帧的crc校验问题

对802.11帧的crc校验是帧主体和帧头,那对帧头的校验具体是怎样的呢? 比如java的crc32这个函数用来进行crc校验 对帧主体,我直接把明文放进去:crc32.update("helloworld".getBytes()) 现在我的帧头是以二进制的位来表示的,比如00001000,这个该怎么校验呢?是crc32.update("00001000")吗?还是把这个二进制转为10进制再转为string和其他的帧头拼接起来getBytes()? 但是这样要是出现"11110001"就会出错

mfc上位机发送数据+最后两个字节要通过crc16校验得出,一起发送

crc16的算法程序加上了,不会使用,不知道怎样才能得到正确的crc校验字节。 其中这两位的校验字节是对前边十四个字节的校验。 可否给个程序例子或者指点一下,谢谢各位~

linux内核驱动模块ko加载时如何绕过CRC校验的问题。

基于种种原因,本人编写了一个驱动ko文件,想在天机II的系统上insmod,由于没有天机II的源码,故而我只能在nubia的内核源码树中编译ko文件,所以编译出来的ko文件在天机上面加载存在CRC校验的问题(内核源码版本不匹配?)。 现在模块加载时的ver_magic问题已经绕过,算是解决了,但是由于模块中还要用到不少内核导出函数,有些函数的CRC校验值可以在其他ko模块中找到,但也有很多找不到,所以加载不起来,很是头疼,现在该如何是好,有没有大神给予下指导。。。

循环冗余校验(CRC)算法的实现

循环冗余校验(CRC)算法的实现 1、设计要求 (1)利用结构体或数组模拟网络数据包结构。 (2)编码实现CRC算法,并将得到的校验位附加到网络数据包相应的位置。 (3)根据数据包的长度,随机生成一个数据包产生突变的位置,并对该位置的bit位模拟突变的产生。 (4)重新利用CRC算法校验该数据包,并指出产生的结果。 (5)CRC能够检出所有的错误吗?如果不能,你能构造出无法检错的实例吗? 2、课程设计报告内容 (1) 给出程序的流程图; (2) 给出程序源码; (3) 给出程序的测试结果。

关于CRC校验的问题,真心求助,各路大神

对于要发送的数据进行crc校验,要求就是: 使用汉明码的生成多项式进行错误检测的 CRC(Cyclic RedundancyCheck)16bit CRC(CCITT))校验 CRC校验倒是蛮简单的,网上都有很多例子,但是这句话的意思是不是使用汉明码的生成多项式作为CRC校验的多项式来校验数据呢????? 比如这个例子: >@EEE00$00MMRD00,校验为BEF5,我反向遍历出他的CRC校验多项式是4b3,有没有大哥懂一点汉明码的生成多项式的知识的,真心求助!!!!!

16位的CRC校验 ,把C实现的,用JAVA实现

//本部分的定义需要根据不同的编译器进行修改 //U8 U16 U32分别表示8位、16位、32位无符号数值 #define U8 unsigned char #define U16 unsigned short #define U32 unsigned int #endif //C文件部分 U16 Crc16CCITT_Table[16]={ /* CRC 16bit余式表 */ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef }; /**************************************************************************** 函数名 : void Crc16CCITT(U8 *pDataIn, U32 DataLen, U8 CrcOut[2]) 描述 : 用移位的方法计算一组数字的16位CRC-CCITT校验值 输入参数 : 1、U8 *pDataIn : 要进行16位CRC-CCITT计算的数 2U32 DataLen : DataIn数组的长度 输出参数 : 1、U8 CrcOut[2] : 16位CRC-CCITT计算的结果 返回值 : 无 ****************************************************************************/ void Crc16CCITT(U8 *pDataIn, U32 DataLen, U8 CrcOut[2]) { U16 Crc = 0; U8 Temp; while (DataLen-- != 0) { Temp = ((U8)(Crc>>8))>>4; Crc <<= 4; Crc ^= Crc16CCITT_Table[Temp^(*pDataIn/16)]; Temp = ((BYTE)(Crc>>8))>>4; Crc <<= 4; Crc ^= Crc16CCITT_Table[Temp^(*pDataIn&0x0f)]; pDataIn++; } CrcOut[0] = Crc/256; CrcOut[1] = Crc%256; }

关于CRC循环冗余校验,如何得到这个数据包的校验码

各位大侠好, 现在在做数据上传时,因CRC校验码错误的问题,一直无法解决。 以下有两个数据包,是正确并通过了服务器检测的数据包: 数据包一: ##0121ST=32;CN=2011;PW=123456;MN=0760S77305385X;CP=&&DataTime=20140123155916;011-Rtd=27.09,011-Flag=N;060-Rtd=0.13,060-Flag=N&&6840 数据包二: ##0121ST=32;CN=2011;PW=123456;MN=0760S77305385X;CP=&&DataTime=20140123155946;011-Rtd=27.09,011-Flag=N;060-Rtd=0.13,060-Flag=N&&5440 数据包中最后4位数是CRC校验码“6840”,“5440”。被校验的数据是除包头##以及表示数据长度的四位数(“0121”)之外,后面的数据段。 请问,上面的数据包如何计算才能得到后面的校验码“6840”,“5440”? 我按照算法编程,对上面的包进行了计算,就是得不出“6840”,“5440”。请各位支招。

java实现 循环冗余校验(CRC)算法

算法的要求是如下: ① 装一个16 位寄存器,所有数位均为1。 ② 取被校验串的一个字节与16 位寄存器的高位字节进行“异或”运算。运算结果放 入这个16 位寄存器。 ③ 把这个16 寄存器向右移一位。 ④ 若向右(标记位)移出的数位是1,则生成多项式1010 0000 0000 0001 和这个寄 存器进行“异或”运算;若向右移出的数位是0,则返回③。 ⑤ 重复③和④,直至移出8 位。 ⑥ 取被校验串的下一个字节 ⑦ 重复③~⑥,直至被校验串的所有字节均与16 位寄存器进行“异或”运算,并移位 8 次。 ⑧ 这个16 位寄存器的内容即2 字节CRC 错误校验码。 校验码按照先高字节后低字节的顺序存放。 我自己理解实现了下: ``` public static short crc16(byte[] data) { short crc = (short) 0xFFFF; short dxs = (short) 0xA001; byte tc; byte sbit; for (int i = 0; i < data.length; i++) { tc = (byte) ((crc & 0xff00) >> 8); crc = (short) (tc ^ data[i]); for (int r = 0; r < 8; r++) { sbit = (byte) (crc & 0x01); crc = (short) (crc >> 1); if (sbit != 0) crc = (short) (crc ^ dxs); } } System.out.println(bytesToHexString(new byte[] { (byte) ((crc & 0xff00) >> 8), (byte) (crc & 0xff) })); return crc; } //将字节数组按16进制输出 public static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (stringBuilder.length() != 0) { stringBuilder.append(","); } if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } ``` 可是我计算出的接口和文档上对不上,不知道哪里有问题?

C# CRC8算法校验问题,如何进行校验

Combined serial number = (ID series * 524288) + serial number. Then the combined serial number must be converted to hexadecimal and insert with the least significant byte first. Below example shows the hex file created for a serial number of 14 and a ID series of 4. This gives 20000E. The serial number is followed by a CRC-8 and at the end the Intel Checksum. The rest of the characters are the same for every time. :100000000E0020E2000000000000000000000000E0 意思如下:(4*524288)+14转换成16进制后为20000e,倒一下,变成0E0020,然后进行CRC-8校验,得到E2,请问这边的E2是如何算出来的,请给出C#的算法。我在网上找了很多C#算法,都算不出是E2,是不是这边算错了?

关于CRC校验的问题~求解释

如果生成多项式G(x)为11010010,以下4个CRC校验比特序列中只有哪个可能是正确的? A. 1101011001 B. 101011011 C. 11011011 D. 1011001 请详细解释,谢谢~

VB 调用crc16校验 dll 返回值不正确

真诚求助,其实什么都写好了就是关键时候掉链子了 如下: C语言写的CRC16 半字节查表 方式校验,dll cpp 程序如下: unsigned short _stdcall CalCRC16(unsigned char *ptr, unsigned char len) { unsigned short crc; unsigned char da; unsigned short crc_ta[16]={ 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef }; crc =0xFFFF; while(len--!=0) { da = ((unsigned char)(crc/256))/16; crc<<=4; crc^=crc_ta[da^(*ptr/16)]; da = ((unsigned char)(crc/256))/16; crc<<=4; crc^=crc_ta[da^(*ptr&0x0f)]; ptr++; } return(crc); } 程序没有错误,单独调试OK,单独用函数 输入数组{0xAB,0x05,0x0A}也能返回正确的校验码DF4E 我用VB调用此dll 程序如下: Private Declare Function CalCRC16 Lib "C:\CRC16.dll\crc16.dll" (ByRef buf() As Byte, ByVal nLen As Long) As Long Private Sub Command1_Click() Dim buf(0 To 2) As Byte buf(0) = &HAB buf(1) = &H5 buf(2) = &HA lngCRC = CalCRC16(buf, 3) Debug.Print Hex(lngCRC) End Sub 编译OK,但返回值不正确,不知道那里错了,那位大神能告知,不胜感激

将下面C++语言版的CRC校验改为C#语言版 谢谢

static unsigned short crc16_update(unsigned short crc, unsigned char a) { int i; crc ^= a; for (i = 0; i < 8; ++i) { if (crc & 1) { crc = (crc >> 1) ^ 0xA001; } else { crc = (crc >> 1); } } return crc; } //------------------ static unsigned short getChk(unsigned char * b,int len) { unsigned short crc=0xffff; while(len--) { crc=crc16_update(crc,*b++); } return crc; }

crc8 校验,百度查了好多,总感觉不对,按道理来说crc8校验的表是固定不变的吧,共256种。

小弟工作中刚好要用到这个,于是网上查了好多,原理搞懂了懂了。但是发现好多博客上校验的表都不一样,代码感觉也怪怪的,下面是两个不同的表,请问有人用过这个吗,有c代码可以发一份参考下吗,谢谢啦。 const unsigned char Crc8Table[256] = { 0x00,0x8D,0x97,0x1A,0xA3,0x2E,0x34,0xB9,0xCB,0x46,0x5C,0xD1,0x68,0xE5,0xFF,0x72, 0x1B,0x96,0x8C,0x01,0xB8,0x35,0x2F,0xA2,0xD0,0x5D,0x47,0xCA,0x73,0xFE,0xE4,0x69, 0x36,0xBB,0xA1,0x2C,0x95,0x18,0x02,0x8F,0xFD,0x70,0x6A,0xE7,0x5E,0xD3,0xC9,0x44, 0x2D,0xA0,0xBA,0x37,0x8E,0x03,0x19,0x94,0xE6,0x6B,0x71,0xFC,0x45,0xC8,0xD2,0x5F, 0x6C,0xE1,0xFB,0x76,0xCF,0x42,0x58,0xD5,0xA7,0x2A,0x30,0xBD,0x04,0x89,0x93,0x1E, 0x77,0xFA,0xE0,0x6D,0xD4,0x59,0x43,0xCE,0xBC,0x31,0x2B,0xA6,0x1F,0x92,0x88,0x05, 0x5A,0xD7,0xCD,0x40,0xF9,0x74,0x6E,0xE3,0x91,0x1C,0x06,0x8B,0x32,0xBF,0xA5,0x28, 0x41,0xCC,0xD6,0x5B,0xE2,0x6F,0x75,0xF8,0x8A,0x07,0x1D,0x90,0x29,0xA4,0xBE,0x33, 0xD8,0x55,0x4F,0xC2,0x7B,0xF6,0xEC,0x61,0x13,0x9E,0x84,0x09,0xB0,0x3D,0x27,0xAA, 0xC3,0x4E,0x54,0xD9,0x60,0xED,0xF7,0x7A,0x08,0x85,0x9F,0x12,0xAB,0x26,0x3C,0xB1, 0xEE,0x63,0x79,0xF4,0x4D,0xC0,0xDA,0x57,0x25,0xA8,0xB2,0x3F,0x86,0x0B,0x11,0x9C, 0xF5,0x78,0x62,0xEF,0x56,0xDB,0xC1,0x4C,0x3E,0xB3,0xA9,0x24,0x9D,0x10,0x0A,0x87, 0xB4,0x39,0x23,0xAE,0x17,0x9A,0x80,0x0D,0x7F,0xF2,0xE8,0x65,0xDC,0x51,0x4B,0xC6, 0xAF,0x22,0x38,0xB5,0x0C,0x81,0x9B,0x16,0x64,0xE9,0xF3,0x7E,0xC7,0x4A,0x50,0xDD, 0x82,0x0F,0x15,0x98,0x21,0xAC,0xB6,0x3B,0x49,0xC4,0xDE,0x53,0xEA,0x67,0x7D,0xF0, 0x99,0x14,0x0E,0x83,0x3A,0xB7,0xAD,0x20,0x52,0xDF,0xC5,0x48,0xF1,0x7C,0x66,0xEB }; const char CRC8Table[]={ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 };

用java 实现 CRC16校验

String str = "V0/SC1234567890ABCDEFGH/IN1017/PN10001088/UN2078/CAS26471-62-5/PK1AK200/20161112//100/10001/"; 将字符串中的字母以及数字,都通过ASCII表转换成二进制数字串,直至最后的一个分隔符“/”,将此二进制数字串进行CRC16的运算,并将计算的结果用大写HEX标识. 表达多项式为: X16 + X12 + X5 + 1 初始值为 0x5368。 请各位大神帮忙写个工具类谢谢

关于CRC校验的一道题,求助

![图片说明](https://img-ask.csdn.net/upload/201602/07/1454847620_648539.png) G(x)那一串是什么意思?

把下面这段c语言的crc校验 转换成java的,麻烦了, 我是实在不会

//crc 之前数据,数据长度 unsigned short CRC16(unsigned char const *buf, unsigned int len) { unsigned short Crc=0xffff; int i; for(i=0; i<len; i++) { Crc = ((Crc >> 8) & 0xFF) ^ CRC16Table [(Crc^ *buf++) & 0xFF]; } return Crc; }

CRC_CCITT校验和PHP

<div class="post-text" itemprop="text"> <p>I have a problem with getting the right checksum of the hex CommandBlock I want to send to the controller.</p> <p>The existing code is in Deplhi, and I am not a good friend with Deplhi, so I want to do it in PHP. The array below is CommandBlock with the checksum (the last 2 bytes) which I have no idea how to get them:</p> <pre><code>$commandBlock = [0x10, 0x02, 0x42, 0x01, 0x02, 0x10, 0x03, **0xa3, 0xd9**]; </code></pre> <p>The only thing I know is that there was used <em>CRC_CCITT()</em> function.</p> </div>

Iso14443 CRC-a和b的校验算法细节

在网上找的要么不清楚要么没提到细节 能不能提供一下代码或者详细的说明文档 谢谢

C#实现串口通讯CRC算法

![图片说明](https://img-ask.csdn.net/upload/201702/16/1487222792_633222.png) 如何实现目标字符输完,通过CRC算法 自动出来计算结果那个框

在中国程序员是青春饭吗?

今年,我也32了 ,为了不给大家误导,咨询了猎头、圈内好友,以及年过35岁的几位老程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助,记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如何应对互联网行业的「中年危机」 一、你以为的人生 刚入行时,拿着傲人的工资,想着好好干,以为我们的人生是这样的: 等真到了那一天,你会发现,你的人生很可能是这样的: ...

程序员请照顾好自己,周末病魔差点一套带走我。

程序员在一个周末的时间,得了重病,差点当场去世,还好及时挽救回来了。

我以为我学懂了数据结构,直到看了这个导图才发现,我错了

数据结构与算法思维导图

String s = new String(" a ") 到底产生几个对象?

老生常谈的一个梗,到2020了还在争论,你们一天天的,哎哎哎,我不是针对你一个,我是说在座的各位都是人才! 上图红色的这3个箭头,对于通过new产生一个字符串(”宜春”)时,会先去常量池中查找是否已经有了”宜春”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”宜春”对象的拷贝对象。 也就是说准确答案是产生了一个或两个对象,如果常量池中原来没有 ”宜春” ,就是两个。...

技术大佬:我去,你写的 switch 语句也太老土了吧

昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!” 来看看小王写的代码吧,看完不要骂我装逼啊。 private static String createPlayer(PlayerTypes p...

Linux面试题(2020最新版)

文章目录Linux 概述什么是LinuxUnix和Linux有什么区别?什么是 Linux 内核?Linux的基本组件是什么?Linux 的体系结构BASH和DOS之间的基本区别是什么?Linux 开机启动过程?Linux系统缺省的运行级别?Linux 使用的进程间通信方式?Linux 有哪些系统日志文件?Linux系统安装多个桌面环境有帮助吗?什么是交换空间?什么是root帐户什么是LILO?什...

将一个接口响应时间从2s优化到 200ms以内的一个案例

一、背景 在开发联调阶段发现一个接口的响应时间特别长,经常超时,囧… 本文讲讲是如何定位到性能瓶颈以及修改的思路,将该接口从 2 s 左右优化到 200ms 以内 。 二、步骤 2.1 定位 定位性能瓶颈有两个思路,一个是通过工具去监控,一个是通过经验去猜想。 2.1.1 工具监控 就工具而言,推荐使用 arthas ,用到的是 trace 命令 具体安装步骤很简单,大家自行研究。 我的使用步骤是...

学历低,无法胜任工作,大佬告诉你应该怎么做

微信上收到一位读者小涛的留言,大致的意思是自己只有高中学历,经过培训后找到了一份工作,但很难胜任,考虑要不要辞职找一份他能力可以胜任的实习工作。下面是他留言的一部分内容: 二哥,我是 2016 年高中毕业的,考上了大学但没去成,主要是因为当时家里经济条件不太允许。 打工了三年后想学一门技术,就去培训了。培训的学校比较垃圾,现在非常后悔没去正规一点的机构培训。 去年 11 月份来北京找到了一份工...

JVM内存结构和Java内存模型别再傻傻分不清了

JVM内存结构和Java内存模型都是面试的热点问题,名字看感觉都差不多,网上有些博客也都把这两个概念混着用,实际上他们之间差别还是挺大的。 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关,本文针对这两个总是被混用的概念展开讲解。 JVM内存结构 JVM构成 说到JVM内存结构,就不会只是说内存结构的5个分区,而是会延展到整个JVM相关的问题,所以先了解下

和黑客斗争的 6 天!

互联网公司工作,很难避免不和黑客们打交道,我呆过的两家互联网公司,几乎每月每天每分钟都有黑客在公司网站上扫描。有的是寻找 Sql 注入的缺口,有的是寻找线上服务器可能存在的漏洞,大部分都...

Google 与微软的浏览器之争

浏览器再现“神仙打架”。整理 | 屠敏头图 | CSDN 下载自东方 IC出品 | CSDN(ID:CSDNnews)从 IE 到 Chrome,再从 Chrome 到 Edge,微软与...

讲一个程序员如何副业月赚三万的真实故事

loonggg读完需要3分钟速读仅需 1 分钟大家好,我是你们的校长。我之前讲过,这年头,只要肯动脑,肯行动,程序员凭借自己的技术,赚钱的方式还是有很多种的。仅仅靠在公司出卖自己的劳动时...

上班一个月,后悔当初着急入职的选择了

最近有个老铁,告诉我说,上班一个月,后悔当初着急入职现在公司了。他之前在美图做手机研发,今年美图那边今年也有一波组织优化调整,他是其中一个,在协商离职后,当时捉急找工作上班,因为有房贷供着,不能没有收入来源。所以匆忙选了一家公司,实际上是一个大型外包公司,主要派遣给其他手机厂商做外包项目。**当时承诺待遇还不错,所以就立马入职去上班了。但是后面入职后,发现薪酬待遇这块并不是HR所说那样,那个HR自...

女程序员,为什么比男程序员少???

昨天看到一档综艺节目,讨论了两个话题:(1)中国学生的数学成绩,平均下来看,会比国外好?为什么?(2)男生的数学成绩,平均下来看,会比女生好?为什么?同时,我又联想到了一个技术圈经常讨...

搜狗输入法也在挑战国人的智商!

故事总是一个接着一个到来...上周写完《鲁大师已经彻底沦为一款垃圾流氓软件!》这篇文章之后,鲁大师的市场工作人员就找到了我,希望把这篇文章删除掉。经过一番沟通我先把这篇文章从公号中删除了...

85后蒋凡:28岁实现财务自由、34岁成为阿里万亿电商帝国双掌门,他的人生底层逻辑是什么?...

蒋凡是何许人也? 2017年12月27日,在入职4年时间里,蒋凡开挂般坐上了淘宝总裁位置。 为此,时任阿里CEO张勇在任命书中力赞: 蒋凡加入阿里,始终保持创业者的冲劲,有敏锐的...

总结了 150 余个神奇网站,你不来瞅瞅吗?

原博客再更新,可能就没了,之后将持续更新本篇博客。

副业收入是我做程序媛的3倍,工作外的B面人生是怎样的?

提到“程序员”,多数人脑海里首先想到的大约是:为人木讷、薪水超高、工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是简单的爱好,还是正经的副业,他们都干得同样出色。偶尔,还能和程序员的特质结合,产生奇妙的“化学反应”。 @Charlotte:平日素颜示人,周末美妆博主 大家都以为程序媛也个个不修边幅,但我们也许...

MySQL数据库面试题(2020最新版)

文章目录数据库基础知识为什么要使用数据库什么是SQL?什么是MySQL?数据库三大范式是什么mysql有关权限的表都有哪几个MySQL的binlog有有几种录入格式?分别有什么区别?数据类型mysql有哪些数据类型引擎MySQL存储引擎MyISAM与InnoDB区别MyISAM索引与InnoDB索引的区别?InnoDB引擎的4大特性存储引擎选择索引什么是索引?索引有哪些优缺点?索引使用场景(重点)...

如果你是老板,你会不会踢了这样的员工?

有个好朋友ZS,是技术总监,昨天问我:“有一个老下属,跟了我很多年,做事勤勤恳恳,主动性也很好。但随着公司的发展,他的进步速度,跟不上团队的步伐了,有点...

我入职阿里后,才知道原来简历这么写

私下里,有不少读者问我:“二哥,如何才能写出一份专业的技术简历呢?我总感觉自己写的简历太烂了,所以投了无数份,都石沉大海了。”说实话,我自己好多年没有写过简历了,但我认识的一个同行,他在阿里,给我说了一些他当年写简历的方法论,我感觉太牛逼了,实在是忍不住,就分享了出来,希望能够帮助到你。 01、简历的本质 作为简历的撰写者,你必须要搞清楚一点,简历的本质是什么,它就是为了来销售你的价值主张的。往深...

离职半年了,老东家又发 offer,回不回?

有小伙伴问松哥这个问题,他在上海某公司,在离职了几个月后,前公司的领导联系到他,希望他能够返聘回去,他很纠结要不要回去? 俗话说好马不吃回头草,但是这个小伙伴既然感到纠结了,我觉得至少说明了两个问题:1.曾经的公司还不错;2.现在的日子也不是很如意。否则应该就不会纠结了。 老实说,松哥之前也有过类似的经历,今天就来和小伙伴们聊聊回头草到底吃不吃。 首先一个基本观点,就是离职了也没必要和老东家弄的苦...

男生更看重女生的身材脸蛋,还是思想?

往往,我们看不进去大段大段的逻辑。深刻的哲理,往往短而精悍,一阵见血。问:产品经理挺漂亮的,有点心动,但不知道合不合得来。男生更看重女生的身材脸蛋,还是...

什么时候跳槽,为什么离职,你想好了么?

都是出来打工的,多为自己着想

程序员为什么千万不要瞎努力?

本文作者用对比非常鲜明的两个开发团队的故事,讲解了敏捷开发之道 —— 如果你的团队缺乏统一标准的环境,那么即使勤劳努力,不仅会极其耗时而且成果甚微,使用...

为什么程序员做外包会被瞧不起?

二哥,有个事想询问下您的意见,您觉得应届生值得去外包吗?公司虽然挺大的,中xx,但待遇感觉挺低,马上要报到,挺纠结的。

当HR压你价,说你只值7K,你该怎么回答?

当HR压你价,说你只值7K时,你可以流畅地回答,记住,是流畅,不能犹豫。 礼貌地说:“7K是吗?了解了。嗯~其实我对贵司的面试官印象很好。只不过,现在我的手头上已经有一份11K的offer。来面试,主要也是自己对贵司挺有兴趣的,所以过来看看……”(未完) 这段话主要是陪HR互诈的同时,从公司兴趣,公司职员印象上,都给予对方正面的肯定,既能提升HR的好感度,又能让谈判气氛融洽,为后面的发挥留足空间。...

面试:第十六章:Java中级开发(16k)

HashMap底层实现原理,红黑树,B+树,B树的结构原理 Spring的AOP和IOC是什么?它们常见的使用场景有哪些?Spring事务,事务的属性,传播行为,数据库隔离级别 Spring和SpringMVC,MyBatis以及SpringBoot的注解分别有哪些?SpringMVC的工作原理,SpringBoot框架的优点,MyBatis框架的优点 SpringCould组件有哪些,他们...

面试阿里p7,被按在地上摩擦,鬼知道我经历了什么?

面试阿里p7被问到的问题(当时我只知道第一个):@Conditional是做什么的?@Conditional多个条件是什么逻辑关系?条件判断在什么时候执...

终于懂了TCP和UDP协议区别

终于懂了TCP和UDP协议区别

立即提问
相关内容推荐