二进制逆序(字节反转)

二进制逆序原文
CRC16算法原文

1 理论分析

二进制逆序,顾名思义就是将低位和高位交换,例如0x23 = 0010 0011 B,逆序后就是1100 0100 B。字节反转在“小端”格式和“大端”格式之间的数据转换是一个必要的操作。
一种比较笨的办法就是将字节里的每一位提取出来,再重新组合,这种方法较为耗费时间,对低端单片机而言极为不利。实际上通过与运算(&)和移位运算,可以轻松的做到这一点。
主要原理:先交换每相邻两位上的数,以后把互相交换过的数看成一个整体,继续进行以2位为单位的交换操作,之后以4为单位,以此类推。 以211= 11010011 B为例:

状态
1101001111010011<—原数
1 11 00 01 111100011<—第一次运算后
1 0 1 11 1 0 010111100<—第二次运算后
1 1 0 0 1 0 1 111001011<—第三次运算后

2 程序实现

/*   ****************************************************************/  
/**  
** @brief CRC校验函数
** @details 需要进行8位字节大小端逆序和,16位字节大小端逆序
** @note  
*/  
/*   ***************************************************************/  
unsigned int _CRC16(unsigned char *puchMsg, unsigned int usDataLen)  
{  
    unsigned int wCRCin = 0xFFFF;  
    unsigned int wCPoly = 0x1021;  
    unsigned char wChar = 0x0000;  

    while (usDataLen--)     
    {  
        wChar = *(puchMsg++); 

        /* 8位交换大小端 */ 
        /* InvertUint8(&wChar,&wChar); */
        // 交换每两位  
        wChar = ((wChar >> 1) & 0x55) | ((wChar & 0x55) << 1);  
        // 交换每四位中的前两位和后两位  
        wChar = ((wChar >> 2) & 0x33) | ((wChar & 0x33) << 2);  
        // 交换每八位中的前四位和后四位  
        wChar = ((wChar >> 4) & 0x0F) | ((wChar & 0x0F) << 4);

        wCRCin ^= (wChar << 8);  
        for(int i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
    }

    /* 16位交换大小端 */
    /* InvertUint16(&wCRCin,&wCRCin); */
    // 交换每两位  
    wCRCin = ((wCRCin >> 1) & 0x5555) | ((wCRCin & 0x5555) << 1);  
    // 交换每四位中的前两位和后两位  
    wCRCin = ((wCRCin >> 2) & 0x3333) | ((wCRCin & 0x3333) << 2);  
    // 交换每八位中的前四位和后四位  
    wCRCin = ((wCRCin >> 4) & 0x0F0F) | ((wCRCin & 0x0F0F) << 4);  
    // 交换相邻的两个字节  
    wCRCin = ((wCRCin >> 8) & 0x00FF) | ((wCRCin & 0x00FF) << 8);  

    return (wCRCin);  
}  

3,博主注

可以把整个过程看出一个递归过程理解起来会容易很多,比如:

00111101先分成0011-1101两部分调换1101-0011
1101先分成11-01两部分调换01-11(0011同理)
01分成0-1调换成1-0(11同理)

可以用递归函数完成这个过程,但32位以内都是没有必要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值