当前位置: 首页 > news >正文

怎么自己建设网站佛山疫情最新情况

怎么自己建设网站,佛山疫情最新情况,如何做购物网站的教程,app开发流程 网站开发一、CRC简介 CRC(Cyclic Redundancy Check),即循环冗余校验,是一种根据网络数据包或电脑文件等数据产生简短固定位数校核码的快速算法,主要用来检测或校核数据传输或者保存后可能出现的错误。CRC利用除法及余数的原理,实现错误侦…

一、CRC简介

CRC(Cyclic Redundancy Check),即循环冗余校验,是一种根据网络数据包或电脑文件等数据产生简短固定位数校核码的快速算法,主要用来检测或校核数据传输或者保存后可能出现的错误。CRC利用除法及余数的原理,实现错误侦测的功能,具有原理清晰、实现简单等优点。注意,CRC校验只能对数据进行检错,而不能对其纠错。因此,在CAN总线上的每个节点一旦发现数据有错,CAN控制器会根据总线仲裁原则和受损报文优先发送原则对已损坏的报文进行自动重传。具体可以参考:《百度百科——CRC》。

二、CRC校验原理

可以参考:《CRC校验原理及实现》、《什么是CRC循环冗余校验,是如何对数据进行计算的?》、《CRC码计算及校验原理的最通俗诠释》等文章。

三、CRC8/CRC16/CRC32

常见的CRC校验类型有CRC8/CRC16/CRC32。其中:

CRC8:一种较短的CRC校验类型,其生成的校验码由8比特组成,即一个字节。这意味着它能提供的唯一校验结果数量为2^8=256种。

CRC16:相较于CRC8,CRC16提供了更强的错误检测能力,其生成的校验码由16比特构成,对应于2^16种不同的校验值。这种扩展提高了算法对单比特错误以及一定长度突发错误序列的检测概率。

CRC32:位于CRC系列顶端的是CRC32,它产生的校验码有32比特,可形成2^32种不同组合。这种级别的CRC校验尤其适用于大数据传输、高可靠性要求的数据完整性保证场合,如ISO 9660文件系统、ZIP压缩文件格式,以及TCP/IP协议栈中的IP头校验等。

具体可以参考:《CRC8/CRC16/CRC32全面对比详解》。

四、FFmpeg源码中,计算CRC校验的实现

FFmpeg源码中通过av_crc函数计算CRC校验,该函数定义在libavutil/crc.c中:

/*** Calculate the CRC of a block.* @param ctx initialized AVCRC array (see av_crc_init())* @param crc CRC of previous blocks if any or initial value for CRC* @param buffer buffer whose CRC to calculate* @param length length of the buffer* @return CRC updated with the data from the given block** @see av_crc_init() "le" parameter*/
uint32_t av_crc(const AVCRC *ctx, uint32_t crc,const uint8_t *buffer, size_t length)
{const uint8_t *end = buffer + length;#if !CONFIG_SMALLif (!ctx[256]) {while (((intptr_t) buffer & 3) && buffer < end)crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8);while (buffer < end - 3) {crc ^= av_le2ne32(*(const uint32_t *) buffer); buffer += 4;crc = ctx[3 * 256 + ( crc        & 0xFF)] ^ctx[2 * 256 + ((crc >> 8 ) & 0xFF)] ^ctx[1 * 256 + ((crc >> 16) & 0xFF)] ^ctx[0 * 256 + ((crc >> 24)       )];}}
#endifwhile (buffer < end)crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8);return crc;
}

形参ctx:输入型参数,指向通过av_crc_get_table函数获取到的CRC table,即初始化的AVCRC数组。

形参crc:输入型参数,先前块的CRC(如果有的话)或CRC的初始值。

形参buffer:输入型参数,指向缓冲区的指针,该缓冲区存放要计算其CRC校验的数据。

形参length:输入型参数,形参buffer指向的缓冲区的长度,单位为字节。

返回值:计算出来的CRC校验。

五、av_crc函数的使用例子

(一)通过av_crc函数计算CRC校验

需要校验的数据如下(以十六进制表示),总共28个字节数据:

02 B0 1D 00 01 C1 00 00 E1 00 F0 00 1B E1 00 F0 00 0F E1 01 F0 06 0A 04 75 6E 64 00

以参数模型为CRC-32/MPEG-2为例,通过 CRC(循环冗余校验)在线计算  得出上面数据的CRC校验为0x08,0x7D,0xE8,0x77:

把FFmpeg中CRC相关的函数移植出来,编写测试例子main.cpp:

#include <stdio.h>
#include <stdint.h>
//#include <stdint-uintn.h>#ifdef __GNUC__
#    define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
#    define AV_GCC_VERSION_AT_MOST(x,y)  (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y))
#else
#    define AV_GCC_VERSION_AT_LEAST(x,y) 0
#    define AV_GCC_VERSION_AT_MOST(x,y)  0
#endif#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__)
#    define av_const __attribute__((const))
#else
#    define av_const
#endif#ifndef av_always_inline
#if AV_GCC_VERSION_AT_LEAST(3,1)
#    define av_always_inline __attribute__((always_inline)) inline
#elif defined(_MSC_VER)
#    define av_always_inline __forceinline
#else
#    define av_always_inline inline
#endif
#endif#define AV_BSWAP16C(x) (((x) << 8 & 0xff00)  | ((x) >> 8 & 0x00ff))
#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16))
#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32))#define AVOnce char
#define AV_ONCE_INIT 0static inline int ff_thread_once(char *control, void (*routine)(void))
{if (!*control) {routine();*control = 1;}return 0;
}#define	EINVAL		22	/* Invalid argument */
#define AVERROR(e) (-(e))   ///< Returns a negative error code from a POSIX error code, to return from library functions.#define CRC_TABLE_SIZE 1024#define av_le2ne32(x) (x)typedef uint32_t AVCRC;typedef enum {AV_CRC_8_ATM,AV_CRC_16_ANSI,AV_CRC_16_CCITT,AV_CRC_32_IEEE,AV_CRC_32_IEEE_LE,  /*< reversed bitorder version of AV_CRC_32_IEEE */AV_CRC_16_ANSI_LE,  /*< reversed bitorder version of AV_CRC_16_ANSI */AV_CRC_24_IEEE,AV_CRC_8_EBU,AV_CRC_MAX,         /*< Not part of public API! Do not use outside libavutil. */
}AVCRCId;static AVCRC av_crc_table[AV_CRC_MAX][CRC_TABLE_SIZE];#define DECLARE_CRC_INIT_TABLE_ONCE(id, le, bits, poly)                                       \
static AVOnce id ## _once_control = AV_ONCE_INIT;                                             \
static void id ## _init_table_once(void)                                                      \
{                                                                                             \av_crc_init(av_crc_table[id], le, bits, poly, sizeof(av_crc_table[id])); \
}#ifndef av_bswap32
static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
{return AV_BSWAP32C(x);
}
#endif#define CRC_INIT_TABLE_ONCE(id) ff_thread_once(&id ## _once_control, id ## _init_table_once)DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM,      0,  8,       0x07)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU,      0,  8,       0x1D)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI,    0, 16,     0x8005)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT,   0, 16,     0x1021)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE,    0, 24,   0x864CFB)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE,    0, 32, 0x04C11DB7)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE, 1, 32, 0xEDB88320)
DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE, 1, 16,     0xA001)int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)
{unsigned i, j;uint32_t c;if (bits < 8 || bits > 32 || poly >= (1LL << bits))return AVERROR(EINVAL);if (ctx_size != sizeof(AVCRC) * 257 && ctx_size != sizeof(AVCRC) * 1024)return AVERROR(EINVAL);for (i = 0; i < 256; i++) {if (le) {for (c = i, j = 0; j < 8; j++)c = (c >> 1) ^ (poly & (-(c & 1)));ctx[i] = c;} else {for (c = i << 24, j = 0; j < 8; j++)c = (c << 1) ^ ((poly << (32 - bits)) & (((int32_t) c) >> 31));ctx[i] = av_bswap32(c);}}ctx[256] = 1;
#if !CONFIG_SMALLif (ctx_size >= sizeof(AVCRC) * 1024)for (i = 0; i < 256; i++)for (j = 0; j < 3; j++)ctx[256 * (j + 1) + i] =(ctx[256 * j + i] >> 8) ^ ctx[ctx[256 * j + i] & 0xFF];
#endifreturn 0;
}const AVCRC *av_crc_get_table(AVCRCId crc_id)
{
#if !CONFIG_HARDCODED_TABLESswitch (crc_id) {case AV_CRC_8_ATM:      CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM); break;case AV_CRC_8_EBU:      CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU); break;case AV_CRC_16_ANSI:    CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI); break;case AV_CRC_16_CCITT:   CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT); break;case AV_CRC_24_IEEE:    CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE); break;case AV_CRC_32_IEEE:    CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE); break;case AV_CRC_32_IEEE_LE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE); break;case AV_CRC_16_ANSI_LE: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE); break;default: ;}
#endifreturn av_crc_table[crc_id];
}uint32_t av_crc(const AVCRC *ctx, uint32_t crc,const uint8_t *buffer, size_t length)
{const uint8_t *end = buffer + length;#if !CONFIG_SMALLif (!ctx[256]) {while (((intptr_t) buffer & 3) && buffer < end)crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8);while (buffer < end - 3) {crc ^= av_le2ne32(*(const uint32_t *) buffer); buffer += 4;crc = ctx[3 * 256 + ( crc        & 0xFF)] ^ctx[2 * 256 + ((crc >> 8 ) & 0xFF)] ^ctx[1 * 256 + ((crc >> 16) & 0xFF)] ^ctx[0 * 256 + ((crc >> 24)       )];}}
#endifwhile (buffer < end)crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8);return crc;
}int main()
{uint8_t cur_section_buf[28] = {0x02, 0xB0, 0x1D, 0x00, 0x01, 0xC1, 0x00, 0x00, 0xE1, 0x00, 0xF0, 0x00, 0x1B, 0xE1, 0x00, 0xF0, 0x00, 0x0F, 0xE1, 0x01, 0xF0, 0x06, 0x0A, 0x04, 0x75, 0x6E, 0x64, 0x00};int crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, sizeof(cur_section_buf));printf("crc:%d\n", crc);return 0;
}

在Linux系统上编译,运行,打印十进制的2011725064,即0x77,0xE8, 0x7D,0x08。可以看到跟上述“CRC在线计算”的计算结果是相符的,只是高低位顺序不一样而已:

(二)通过av_crc函数判断CRC校验是否正确

av_crc函数还有一个用途是用来判断一段包含CRC校验的数据中,CRC校验是否正确。我们改写上面的man.cpp:

    uint8_t cur_section_buf[32] = {0x02, 0xB0, 0x1D, 0x00, 0x01, 0xC1, 0x00, 0x00, 0xE1, 0x00, 0xF0, 0x00, 0x1B, 0xE1, 0x00, 0xF0, 0x00, 0x0F, 0xE1, 0x01, 0xF0, 0x06, 0x0A, 0x04, 0x75, 0x6E, 0x64, 0x00, 0x08, 0x7D, 0xE8, 0x77};  int crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, sizeof(cur_section_buf));printf("crc_valid:%d\n", crc_valid);

重新编译,运行,打印“1”表示CRC校验正确,打印|“0”表示校验不正确:

http://www.dinnco.com/news/18854.html

相关文章:

  • 求有题目做的学习网站百度统计app下载
  • 企业微信网站怎么建设优化什么
  • 做课展网站大连seo优化
  • 自己做的手工放在哪个网站卖搜索引擎营销的实现方法
  • 济南专业手机端网站建设国内免费建网站
  • 需要做网站建设的公司网站seo优化心得
  • 一般网站后台都是哪里做免费刷粉网站推广
  • 容桂网站制作信息最近的热点新闻
  • 网站设计顺德线上培训机构有哪些
  • 做网站设计和推广衡阳seo服务
  • b2c电子商务网站的企业类型seo技术外包
  • app软件下载大全太原关键词优化公司
  • django做网站比较容易网店营销推广
  • 网站建设作网络推广人员是干什么的
  • 做 网站 技术支持 抓获 互助谷歌seo外链平台
  • 品牌网站建设c重庆微博推广方法有哪些
  • 联盟文明网站建设有新seo推广有哪些方式
  • 南京哪家做网站比较好厦门搜索引擎优化
  • 野马视觉传媒网站建设江苏网站推广公司
  • 要找做冲压件的厂去哪个网站找成都关键词seo推广平台
  • 360网站图标怎么做的网络优化
  • 最 的wordpress书潍坊网站seo
  • 网站建设方案ppt模板磁力猫官网cilimao
  • 大连做网站科技有限公司工具刷网站排刷排名软件
  • 做设计网上揽活哪个网站最好关键词推广效果分析
  • qq网站登录入口百度快照有什么用
  • 怎么做网站旅游宣传上海网络推广需要多少
  • 肇庆网站建设方案咨询谷歌seo怎么优化
  • 做软件下载网站百度点击器找名风
  • 公司静态网站模板下载上海搜索引擎推广公司