版权声明:本文为CSDN博主「leumber」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/leumber/article/details/54311811

CRC16常见的标准有以下几种,被用在各个规范中,其算法原理基本一致,就是在数据的输入和输出有所差异,下边把这些标准的差异列出,并给出C语言的算法实现。

CRC16_CCITT:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0x0000异或

CRC16_CCITT_FALSE:多项式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在后,高位在前,结果与0x0000异或

CRC16_XMODEM:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在后,高位在前,结果与0x0000异或

CRC16_X25:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

CRC16_MODBUS:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或

CRC16_IBM:多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0x0000异或

CRC16_MAXIM:多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

CRC16_USB:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0xFFFF异或

模式

多项式

初始值

数据位序

结果处理

CRC16_CCITT

x16+x12+x5+1(0x1021)

0x0000

低位在前,高位在后

与0x0000异或

CRC16_CCITT_FALSE

x16+x12+x5+1(0x1021)

0xFFFF

低位在后,高位在前

与0x0000异或

CRC16_XMODEM

x16+x12+x5+1(0x1021)

0x0000

低位在后,高位在前

与0x0000异或

CRC16_X25

x16+x12+x5+1(0x1021)

0x0000

低位在后,高位在前

与0xFFFF异或

CRC16_ MODBUS

x16+x15+x2+1(0x8005)

0xFFFF

低位在前,高位在后

与0x0000异或

CRC16_ IBM

x16+x15+x2+1(0x8005)

0x0000

低位在前,高位在后

与0x0000异或

CRC16_ MAXIM

x16+x15+x2+1(0x8005)

0x0000

低位在前,高位在后

与0xFFFF异或

CRC16_ USB

x16+x15+x2+1(0x8005)

0xFFFF

低位在前,高位在后

与0xFFFF异或

多项式产生:
如x16+x12+x5+1
x16表示第16位为1,x5表示第5位为1
(1 << 16) | (1 << 12) | (1 << 5) | (1) = 0x11021
但是CRC16只取低16位,写成16进制数就是 0x1021

CRC16的算法原理:

1.根据CRC16的标准选择初值CRCIn的值。

2.将数据的第一个字节与CRCIn高8位异或。

3.判断最高位,若该位为 0 左移一位,若为 1 左移一位再与多项式Hex码异或。

4.重复3直至8位全部移位计算结束。

5.重复将所有输入数据操作完成以上步骤,所得16位数即16位CRC校验码。
根据算法原理与标准要求就能简单的写出具体程序:

unsigned short CRC16_CCITT(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0x0000;
  unsigned short wCPoly = 0x1021;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin) ;
}
unsigned short CRC16_CCITT_FALSE(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0xFFFF;
  unsigned short wCPoly = 0x1021;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  return (wCRCin) ;
}
unsigned short CRC16_XMODEM(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0x0000;
  unsigned short wCPoly = 0x1021;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  return (wCRCin) ;
}
 
unsigned short CRC16_X25(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0xFFFF;
  unsigned short wCPoly = 0x1021;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin^0xFFFF) ;
}
 
unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0xFFFF;
  unsigned short wCPoly = 0x8005;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin) ;
}
unsigned short CRC16_IBM(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0x0000;
  unsigned short wCPoly = 0x8005;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin) ;
}
unsigned short CRC16_MAXIM(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0x0000;
  unsigned short wCPoly = 0x8005;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin^0xFFFF) ;
}
unsigned short CRC16_USB(unsigned char *puchMsg, unsigned int usDataLen)
{
  unsigned short wCRCin = 0xFFFF;
  unsigned short wCPoly = 0x8005;
  unsigned char wChar = 0;
  
  while (usDataLen--)     
  {
        wChar = *(puchMsg++);
        InvertUint8(&wChar,&wChar);
        wCRCin ^= (wChar << 8);
        for(int i = 0;i < 8;i++)
        {
          if(wCRCin & 0x8000)
            wCRCin = (wCRCin << 1) ^ wCPoly;
          else
            wCRCin = wCRCin << 1;
        }
  }
  InvertUint16(&wCRCin,&wCRCin);
  return (wCRCin^0xFFFF) ;
}
void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
{
    int i;
    unsigned char tmp[4];
    tmp[0] = 0;
    for(i=0;i< 8;i++)
    {
      if(srcBuf[0]& (1 << i))
        tmp[0]|=1<<(7-i);
    }
    dBuf[0] = tmp[0];
    
}
void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf)
{
    int i;
    unsigned short tmp[4];
    tmp[0] = 0;
    for(i=0;i< 16;i++)
    {
      if(srcBuf[0]& (1 << i))
        tmp[0]|=1<<(15 - i);
    }
    dBuf[0] = tmp[0];
}
void InvertUint32(unsigned int *dBuf,unsigned int *srcBuf)
{
    int i;
    unsigned int tmp[4];
 
    tmp[0] = 0;
    
    for(i=0;i< 32;i++)
    {
      if(srcBuf[0]& (1 << i))
        tmp[0]|=1<<(15 - i);
    }
    dBuf[0] = tmp[0];
}

———————————————— 
版权声明:本文为CSDN博主「leumber」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/leumber/article/details/54311811

【转载】CRC16大全相关推荐

  1. web server大全之GoAhead移植(转载)

    转自:http://linux.chinaunix.net/techdoc/develop/2009/06/19/1119124.shtml 注:最近在做goAhead web server和移植其到 ...

  2. Jquery 选择器大全 【转载】

    选择器是jQuery最基础的东西,本文中列举的选择器基本上囊括了所有的jQuery选择器,也许各位通过这篇文章能够加深对jQuery选择器的理解,它们本身用法就非常简单,我更希望的是它能够提升个人编写 ...

  3. 转载:常用正则表达式大全!(例如:匹配中文、匹配html)

    常用正则表达式大全!(例如:匹配中文.匹配html) 匹配中文字符的正则表达式: [u4e00-u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包括汉字在内):[ ...

  4. Visio 快捷大全(转载)

    Visio 快捷大全 时间:2011-11-20 11:59:48  来源:  作者: 非常好用的制图软件.尤其在系统结构设计方面,能快速勾画出系统结构图. "帮助"任务窗格和&q ...

  5. Android Intent 大全[转载]

    Android Intent 大全     android 中intent是经常要用到的.不管是页面牵转,还是传递数据,或是调用外部程序,系统功能都要用到intent.         ★intent ...

  6. 转载《全国研究生考试专业课资料大全(部分资料)》

    研究生考试专业课整理后的资料大全(部分资料),图示资料都有,有偿提供2元/份,没有的就没有了,想要资料可以提问 目录 (有偿提供,替朋友转载,扫描下方二维码提问,或者向博主扫描提问即可获得,2元/份) ...

  7. Android 2.3 API改变大全(转载)

    遇到OOM问题,需要使用VMRuntime类的时候才发现,原来2.3被移除了,想知道它是否有替代类?留下脚印,再继续... Android 2.3 API改变大全 作者: Android开发网原创 时 ...

  8. SQL语句操作大全(本文系转载)

    SQL语句操作大全(本文系转载) SQL语句操作大全(本文系转载) --通过知识共享树立个人品牌. 本文分为以下六个部分: 基础部分 提升部分 技巧部分 数据开发-经典部分 SQL Server基本函 ...

  9. Response. AppendHeader使用大全及文件下载.net函数使用注意点(转载)

    Response. AppendHeader使用大全文件下载,指定默认名 Response.AddHeader("content-type","application/x ...

最新文章

  1. android4.0 菜单,三大主流安卓4.0界面解析 MIUI最实用
  2. 根据经纬度显示地图轨迹
  3. python 控制手机摄像头_python+open cv调用手机摄像头,保存文件
  4. Nodejs学习笔记(二)——模块
  5. HCL安装和使用模拟器中遇到的问题
  6. python读取文件乱码
  7. JSK-399 绝对值最小的数【大数】
  8. HDU2050 折线分割平面【组合】
  9. multisim仿真D触发器设计的模六计数器并在数码管显示0-5
  10. centos bond配置文件示例
  11. 告诉你一个真实的全球化
  12. Matlab R2016b简体中文版安装教程(附Matlab R2016b百度网盘下载地址)
  13. Python实现简单的用户管理系统
  14. 教你做一个最简版的倒计时计时器,新手也能秒懂。
  15. 【系统优化】解决windows11桌面切换卡顿(非重装以及关闭特效)
  16. 你的个人所得税完税证明看准了吗?
  17. 自行更换iPhone 6s 手机电池 | 工序步骤
  18. 2020年Android开发的未来发展方向该如何走?
  19. 产品运营常踩的七大坑,你踩过吗?
  20. Python数据分析——数据基础

热门文章

  1. 一口气实现交通大数据爬取与Python可视化(含数据分享)
  2. laysns模板系统仿善恶模版 完美自适应
  3. cloudSim学习
  4. ubuntu 18.04 三五分钟即可一键安装ROS系统(亲测有效)
  5. SQL中 % ,_,【】,【^】通配符的的使用
  6. 金工如何运用计算机思维,金工实训心得体会
  7. H3C基础配置文档抄录14-虚拟化配置
  8. 2022R2移动式压力容器充装考试试题模拟考试平台操作
  9. java宝典_java宝典
  10. c语言冒泡排序与二分法排序