二进制逆序(字节反转)

来源:互联网 发布:万方学术期刊数据库 编辑:程序博客网 时间:2024/06/08 02:19

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

1 理论分析

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

状态 1 1 0 1 0 0 1 1 11010011<—原数 1 1 1 0 0 0 1 1 11100011<—第一次运算后 1 0 1 1 1 1 0 0 10111100<—第二次运算后 1 1 0 0 1 0 1 1 11001011<—第三次运算后

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位以内都是没有必要的。