CRC16(X16+X15+X2+1) source code

该博客展示了CRC-16校验的两种实现方式,分别是对高比特先编码和后编码,并提供了计算CRC-16的函数。通过示例代码演示了如何对字节序列进行CRC校验,包括初始化、位移和异或操作。同时,还提供了计算CRC-16的查表方法,提高计算效率。
#include <stdio.h> 
//x16+x15+x2+1: encode high bit before low bit ..[high bit...low bit] 
unsigned short crc16(unsigned char data, unsigned short crc) {
	unsigned short ccitt16 = 0x8005;
	int i;
	crc ^= (data<<8);
	for (i=0; i<8; i++){
		if (crc & 0x8000){
		   crc <<= 1;
		   crc ^= ccitt16;
		}
		else{
		   crc <<= 1;
		}
	}
	return crc;
}
//x16+x15+x2+1: encode high bit after low bit ..[low bit...high bit]. 
unsigned short crc16_r(unsigned char data, unsigned short crc){
	unsigned short ccitt16 = 0xa001;    //(0x8005->[reverse]->0xa001)
	int i;
	crc ^= data;
	for (i=0; i<8; i++){
		if (crc & 1){
		   crc >>= 1;
		   crc ^= ccitt16;
		}
		else{
		   crc >>= 1;
		}
	}
	return crc;
}

unsigned short calculate_crc16(unsigned char* buf, int len, unsigned short crc){
    unsigned short crc16_table[256];
	for(unsigned int i=0; i<256; i++){
		crc16_table[i] = crc16(i, 0);
	}
	for(unsigned int i=0; i<len; i++){
		crc = crc16_table[((crc>>8)^buf[i])&0xff]^(crc<<8);	
	}
	return crc;
}

unsigned short calculate_crc16_r(unsigned char* buf, int len, unsigned short crc){
    unsigned short crc16_table_r[256];
	for(unsigned int i=0; i<256; i++){
		crc16_table_r[i] = crc16_r(i, 0);
	}
	for(unsigned int i=0; i<len; i++){
		crc = crc16_table_r[((crc)^buf[i])&0xff]^(crc>>8);	
	}
	return crc;
}

int main()
{
	unsigned short crc = 0;
	unsigned char buf[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10};
	int len = sizeof(buf)/sizeof(unsigned char);
	//CRC-16:init_crc=0x0, result ^= 0, in/out_put_data(no reverse)
	crc = calculate_crc16(buf, len, 0);
	printf("crc16 = 0x%x\n", crc);
	//CRC-16/IBM:init_crc=0x0, result ^= 0, in/out_put_data(reverse)
	crc = calculate_crc16_r(buf, len, 0);
	printf("crc16_r = 0x%x\n", crc);
    return 0;
}

Useful Reference link

<think>好的,用户的问题是关于在MATLAB中使用CRC-16校验,生成多项式是x^16 + x^15 + x^2 + 1。首先,我需要确认这个多项式的正确表示方式。通常,CRC多项式可以用不同的表示方法,比如十六进制或者二进制。这个多项式对应的二进制应该是从最高位到最低位,每一位代表是否存在对应的项。这里,x^16到x^0,其中x^16、x^15、x^2和x^0(即常数项1)存在,所以二进制表示为1 1000 0000 0000 0101,也就是0x18005(十六进制)。不过,可能需要确认是否反转,因为有些CRC标准会使用反转的多项式。 接下来,用户需要如何在MATLAB中实现这个CRC计算。MATLAB中有内置的通信工具箱,提供了crc.generator函数,可以配置不同的多项式。我需要写出如何设置该多项式的代码,并演示如何生成CRC校验码。同时,还需要注意初始值、输入输出的处理,比如是否反转输入或输出等参数是否正确设置。 另外,如果用户没有通信工具箱,可能需要手动实现CRC计算。这涉及到移位寄存器的方法,按位处理每个输入数据,进行异或和移位操作。这里需要编写一个函数,接受数据和多项式,然后计算CRC值。需要注意的是,初始值通常为0xFFFF,处理每个字节的每一位,高位优先还是低位优先,以及最后的异或值是否需要应用。根据常见的CRC-16变种,比如CRC-16-IBM,初始值可能是0xFFFF,异或输出为0x0000,输入是否反转等参数需要正确设置。 用户的问题中提到的多项式x^16 +x^15 +x^2 +1,对应的二进制是1 10000000 00000101,即0x18005。但有些情况下,多项式可能会被反转,比如CRC-16-CCITT使用0x1021,其反转形式是0x8408。因此,需要确认是否在生成器中使用多项式直接表示还是反转后的形式。根据MATLAB的文档,crc.generator的Polynomial属性是直接按照最高位到最低位的顺序,所以应该直接使用0x18005作为多项式。 在手动实现的情况下,可能需要将多项式转换为移位的处理方式。例如,初始CRC寄存器设为全1(0xFFFF),然后对于输入数据的每个位,与寄存器的最高位进行异或,然后左移一位,如果最高位为1,则与多项式进行异或。这里需要注意的是,多项式通常省略最高位的1,只处理剩下的位,所以0x18005对应的二进制是1 1000 0000 0000 0101,去掉最高位后,是0x8005,但可能需要调整,或者是否包括最高位。可能这里需要进一步确认,但通常在CRC计算中,多项式是17位的(包括x^16),所以在代码中处理时,可能使用0x8005,并将最高位隐式处理。 另外,用户可能想知道如何验证他们的CRC实现是否正确。可以建议使用已知的测试向量,例如对特定输入数据计算CRC并检查结果是否符合预期。 最后,要提出相关问题,涵盖CRC参数的不同方面,比如多项式表示、初始值、反转设置、测试方法等。</think><< 在Matlab中实现CRC-16校验(使用多项式x^16 + x^15 + x^2 + 1)的方法如下: 1. **使用通信工具箱的官方函数**: ```matlab % 定义生成多项式(十六进制表示) poly = [1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1]; % x^16 + x^15 + x^2 + 1 的二进制形式 polyHex = '18005'; % 对应的十六进制表示 % 创建CRC生成器对象 crcGen = comm.CRCGenerator(... 'Polynomial', polyHex,... 'InitialConditions', ones(1,16),... % 初始值全1 'DirectMethod', true); % 输入数据(示例) data = randi([0 1], 1, 64); % 生成64位随机数据 % 计算CRC codeword = crcGen(data'); ``` 2. **手动实现CRC算法**: ```matlab function crc = customCRC16(data) poly = 0x8005; % 多项式表示(隐式最高位) crc = 0xFFFF; % 初始值 for i = 1:length(data) crc = bitxor(crc, bitshift(uint16(data(i)), 8)); for j = 1:8 if bitand(crc, 0x8000) crc = bitxor(bitshift(crc, 1), poly); else crc = bitshift(crc, 1); end crc = bitand(crc, 0xFFFF); % 保持16位 end end end ``` **关键参数解释**: - 多项式0x18005对应二进制`1 1000 0000 0000 0101`,其中最高位x^16CRC计算中通常隐式处理 - 初始值0xFFFF是CRC-16/IBM的典型配置 - 直接法(DirectMethod)表示使用非反转处理顺序
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值