• CRC16_C语言实现


    计算实现CRC16,

    可以通过配置,初值、多项式、输出入是否反转、输出是否反转、结果异或值来选定不同的模式。

    /*
    **************************************************************************************************************
    * 函数名称:     InvertUint8
    * 函数功能:     将uint8类型的数字进行bit全部反转
    * 函数入口:     dBuf    [out]   待反转的值
                    srcBuf  [in]    反转后的值
    * 函数返回:        计算CRC的结果
    ***************************************************************************************************************/
    
    static 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];
    }
    
    /*
    **************************************************************************************************************
    * 函数名称:     InvertUint16
    * 函数功能:     将uint16类型的数字进行bit全部反转
    * 函数入口:     dBuf    [out]   待反转的值
                    srcBuf  [in]    反转后的值
    * 函数返回:        计算CRC的结果
    ***************************************************************************************************************/
    static 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];
    }
    
    
    /*
    **************************************************************************************************************
    * 函数名称:     CRC16
    * 函数功能:     计算CRC16
    * 函数入口:     puchMsg    [in]    待计算的数据
                    usDataLen  [in]    待计算数据的长度
    * 函数返回:        计算CRC的结果
    ***************************************************************************************************************/
    unsigned short CRC16(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);        //输出数据反转,根据模式进行选择是否启用
        
        wCRCin &= 0xFFFF;
        
        wCRCin ^= 0xFFFF;                    //输出异或,根据模式设置异或的数值
        
        return (wCRCin) ;
    }
    CRC16.c
    #include <stdio.h>
    
    /*
    **************************************************************************************************************
    * 函数名称:     InvertUint8
    * 函数功能:     将uint8类型的数字进行bit全部反转
    * 函数入口:     dBuf    [out]   待反转的值
                    srcBuf  [in]    反转后的值
    * 函数返回:        计算CRC的结果
    ***************************************************************************************************************/
    
    static 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];
    }
    
    /*
    **************************************************************************************************************
    * 函数名称:     InvertUint16
    * 函数功能:     将uint16类型的数字进行bit全部反转
    * 函数入口:     dBuf    [out]   待反转的值
                    srcBuf  [in]    反转后的值
    * 函数返回:        计算CRC的结果
    ***************************************************************************************************************/
    static 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];
    }
    
    
    /*
    **************************************************************************************************************
    * 函数名称:     CRC16
    * 函数功能:     计算CRC16
    * 函数入口:     puchMsg    [in]    待计算的数据
                    usDataLen  [in]    待计算数据的长度
    * 函数返回:        计算CRC的结果
    ***************************************************************************************************************/
    unsigned short CRC16(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);        //输出数据反转,根据模式进行选择是否启用
        
        wCRCin &= 0xFFFF;
        
        wCRCin ^= 0xFFFF;                    //输出异或,根据模式设置异或的数值
        
        return (wCRCin) ;
    }
    
    
    
    int main(int argc,char *argv[])
    {
        unsigned char     in_data[4]={0x31,0x32,0x33,0x34};
        unsigned int     in_len = 4;
        unsigned short     out_data;
        
        out_data = CRC16(in_data,in_len);
        printf("CRC16 %02X 
    ",out_data);
        
    
        
        return 0;
    }
  • 相关阅读:
    php中的抽象方法和抽象类,简单明了,一点通
    PHP_保留两位小数并且四舍五入(可用于精度计算)_保留两位小数并且不四舍五入
    如何使用php生成唯一ID的4种方法
    Redis案例——商品秒杀,购物车
    centos+python2+apache2+django环境搭建
    前端上传图片并显示
    通过容器提交镜像(docker commit)以及推送镜像(docker push)
    Name or service not known原因大全
    VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti
    win10家庭版VMware,禁用Device/Credential Guard不兼容问题
  • 原文地址:https://www.cnblogs.com/doitjust/p/14805614.html
Copyright © 2020-2023  润新知