CRC算法

这篇具有很好参考价值的文章主要介绍了CRC算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、定义

  • CRC(Cyclic Redundancy Check):循环冗余检验;
  • 多项式:例如有多项式y=x16+x12+x5+1,可用二进制表达为y=1 0001 0000 0010 0001;
  • 模二除法:类似于“算数除法”,但无借位;如100101除以1110,结果得到商为11,余数为1,如图:CRC算法

二、计算原理

  1. 确定多项式y;
  2. 将需要计算的数据x左移k-1位,得出x1;(k=多项式y的位数)
  3. 用模二除法,将数据x1除以多项式y;
  4. 计算的k-1位的余数即为数据x的CRC校验值;(计算的次数为数据x的位数)

如:多项式y=x4 + x3 + 1,计算数据10110011的CRC校验值为0100;
CRC算法

三、基本算法(手算)

  1. 假设需要对3个字节的数据流(byte[0]、byte[1]、byte[2])做crc16计算;
  2. 数据流左移16位,变成:byte[0]、byte[1]、byte[2]、crc[0]、crc[1];
  3. 对40位数据做模二除法;
  4. 所得的16位余数为crc16的校验码;

效果类似于:

uint16_t get_crc16(uint8_t* buffer, uint16_t length)
{
	uint32_t data, crc_val = 0;
	uint8_t i;

	while (length--) {
		data = *buffer++;
        crc_val ^= (data << 16);	//异或的具体原因不清楚。猜测是为了将上一个字节的crc校验码承接下去

		for (i = 0; i < 8; i++) {
			if (crc_val & 0x800000) {
				crc_val = crc_val ^ ((poly | 0x10000) << 7);
			} else {}
			crc_val <<= 1;
		}
	}
	crc_val >>= 8;	//结果在高16位,所以要右移8位

	return crc_val;
}

四、计算机算法(比特型算法)

  1. 假设需要对3个字节的数据流(byte[0]、byte[1]、byte[2])做crc16计算;
  2. 数据流左移16位,变成:byte[0]、byte[1]、byte[2]、crc[0]、crc[1];
  3. 取数据流高16位数据(byte[0]、byte[1]),放到16位的寄存器中;
  4. 如果寄存器的最高位为1,则寄存器先左移一次(寄存器低位的值从下一个字节获得),再对寄存器和多项式做一次异或计算。否则则寄存器直接左移一次(寄存器低位的值从下一个字节获得);

为什么变成了先左移一次?如果不先左移,其实会发现如果数据流最高bit为1,最终最高1bit在每轮计算中结果都是0。因此数据流的最高bit其实不需要进行计算,直接右移就行。并且,这个方式需要忽略多项式的最高bit,本来是17位的多项式,只需要16位来表示,那么16位的寄存器刚好可以放下多项式的值。

  1. 如果数据流没有全部都移到寄存器,重复上一步;
  2. 最后得到的寄存器的值为crc16的校验码;

函数实现如下:

uint16_t get_crc16(uint8_t* buffer, uint16_t length)
{
	uint32_t data, crc_val = 0;
	uint8_t i;

	while (length--) {
		data = *buffer++;
        crc_val ^= (data << 8);

		for (i = 0; i < 8; i++) {
			if (crc_val & 0x8000) {
				crc_val = (crc_val << 1) ^ poly;
			} else {
			    crc_val <<= 1;
			}
		}
	}
	return crc_val;
}

加入输入翻转、输出翻转、输出异或、初始值后的函数实现:

uint32_t get_ref(uint32_t num, uint8_t bit)
{
	uint32_t ret = 0;
	for (uint8_t i = 0; i < bit; i++) {
		if (num & 0x01) {
			ret |= (0x01 << (bit - i - 1));
		} else {}
		num >>= 1;
	}
	return ret;
}

uint16_t get_crc16(uint8_t* buffer, uint16_t length)
{
	uint16_t data, crc_val = init;  //初始值

	while (length--) {
		data = *buffer++;
		if (ref_in) {
			data = get_ref(data, 8);  //计算输入翻转
		} else {}
		crc_val ^= (data << 8);

		for (uint8_t i = 0; i < 8; i++) {
			if (crc_val & 0x8000) {
				crc_val = (crc_val << 1) ^ poly;
			} else {
				crc_val <<= 1;
			}
		}
	}
	if (ref_out) {
		crc_val = get_ref(crc_val, 16);  //计算输出翻转
	} else {}
	crc_val ^= xor_out;  //计算输出异或

	return crc_val;
}

部分内容参考于:

https://blog.csdn.net/ydyuse/article/details/105395368文章来源地址https://www.toymoban.com/news/detail-477608.html

到了这里,关于CRC算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • CRC(循环冗余校验码的校验方法)

    CRC(循环冗余校验码的校验方法)

    5个关键点: 1.信息码:即给出要校验的二进制码 2.生成多项式:一般多项式会给,从最高位的指数位数就可以得到有几个校验码;如果没给多项式,肯定会给个多项式二进制码,根据它来推就行(具体推的规律,下面会讲) 3.校验位:由多项式的最高位指数得出 4.多项式对应

    2024年02月08日
    浏览(8)
  • 【基础知识】CRC(循环冗余校验)直接计算和查表法

    【基础知识】CRC(循环冗余校验)直接计算和查表法

    校验是什么,个人理解就是经过一个算法,使用大量数据(几MB的数据)生成较小长度的一串信息(如16Bit),并切要做到 原数据不同时,生成的信息大概率不同(不是加密算法不考虑刻意造数据的情况) 原数据中任意一个或几个数据出现错误时,生成的信息不同(所有的原信

    2024年02月05日
    浏览(11)
  • 计算机网络:数据链路层之差错控制、奇偶校验码、CRC循环冗余码、海明码

    计算机网络:数据链路层之差错控制、奇偶校验码、CRC循环冗余码、海明码

    带你度过期末难关 文章目录 一、差错控制 1、冗余编码 2、编码VS编码 二、检错编码 1、奇偶校验码 2、CRC循环冗余码 三、纠错编码————海明码 海明距离 1、确定校验码位数r 2、确定校验码和数据的位置 3、求出校验码的值 4、检错并纠错 纠错的方法一: 纠错方法二: 总

    2024年02月04日
    浏览(8)
  • CRC8检验算法(C语言实现)

    初始值:0xFF 多项式 :X^8+X^2+X^1+1,即0x31 结果异或值:0x00 直接计算法: 查表法:

    2024年02月20日
    浏览(10)
  • DeepSpeed零冗余优化器Zero Redundancy Optimizer

    DeepSpeed零冗余优化器Zero Redundancy Optimizer

    内容 零概述 培训环境 启用零优化 训练 1.5B 参数 GPT-2 模型 训练 10B 参数 GPT-2 模型 使用 ZeRO-Infinity 训练万亿级模型 使用 ZeRO-Infinity 卸载到 CPU 和 NVMe 分配 Massive Megatron-LM 模型 以内存为中心的平铺 注册外部参数 提取权重 如果您还没有这样做,我们建议您在逐步完成本教程之

    2024年02月09日
    浏览(9)
  • 计算机网络----CRC冗余码的运算

    计算机网络----CRC冗余码的运算

    冗余码是用于在数据链路层的通信链路和传输数据过程中可能会出错的一种检错编码方法(检错码)。 原理:发送发把数据划分为组,设每组 K 个比特,在其后添加供差错检验用的 n 位冗余码,( K+n )比特一起发送。 过程: 注意: 模二除法运算的过程相当于 异或 。 因为

    2024年02月12日
    浏览(10)
  • CRC冗余校验的原理和FPGA实现思路

    CRC冗余校验的原理和FPGA实现思路

    CRC校验码,顾名思义是用于 校验 的。它可以用于检测数据传输过程中是否出现错误(某些位,或某几位,或者某块区域位错误),反正 可以知道数据出错了,但是不能纠错 。 CRC校验,本质上是模2除法求余。将发送信息 M 当做被除数,发送方和接收方共同约定一个除数 G

    2024年02月08日
    浏览(10)
  • JS十六进制,CRC冗余,小程序发送蓝牙数据,十六进制GBK编码转换等

    小程序问题:https://kf.qq.com/faq/170705YVZFZZ170705eyI7Rr.html 调用: 注意:这里的true和false代表是否大端小端转换 调用: 调用: 调用: 调用: 调用: 此代码写到小程序utils目录下的utuils.js文件中 调用:页面最上边先引入,然后再使用 调用: 这里发送buffer1给小程序公用api就可 调

    2024年02月16日
    浏览(14)
  • 电脑提示数据错误循环冗余检查怎么办?

    电脑提示数据错误循环冗余检查怎么办?

    有些时候,我们尝试在磁盘上创建分区或清理硬盘时,还可能会遇到这个问题:数据错误循环冗余检查。这是如何导致的呢?我们又该如何解决这个问题呢?下面我们就来了解一下。 数据错误循环冗余检查怎么解决呢?在回答这个问题之前我们需要先了解一下导致问题的原因

    2024年02月12日
    浏览(10)
  • 电脑磁盘数据错误(循环冗余检查)的原因以及解决办法

    造成的原因 出现这种情况,是因为你的这个文件有某些数据记录不正确,也有可能硬盘某处物理损坏读不过去(也就是硬盘有坏道)。通常情况下造成的原因有长时间不关机,软件没退出强制性关机,磁盘检查和优化时强制性退出所导致的。 解决办法 如果是机械硬盘的通道

    2024年02月12日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包