1. 程式人生 > >二進位制逆序(位元組反轉)

二進位制逆序(位元組反轉)

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