我正在使用一些遗留代码,我遇到了一个函数,它显然用于在任意长的字段上执行网络字节顺序转换(大于ntohl可以处理的)。
我无法理解它是否足以判断它是否正在执行除了在msg缓冲区范围内反转字节顺序之外的任何事情(或者即使它会可靠地执行此操作)。有人可以帮我打破这个并分析它,这样我就可以用更容易理解的东西(或者至少评论它)代替它!?
void swapit(unsigned char *msg, int length) {
for(;length>0;length--, msg++) {
*msg = ((*msg * 0x0802LU & 0x22110LU) |
(*msg * 0x8020LU & 0x88440LU)) *
0x10101LU >> 16;
}
}
答案 0 :(得分:20)
要了解其工作原理,请考虑将操作应用于位模式abcdefgh
。
对于.
,我将使用0
表示二进制数,因此非零位突出。
第一个子表达式是:
........ ........ abcdefgh
* ........ ....1... ......1. (0x0802)
= .....abc defgh..a bcdefgh.
& ......1. ..1....1 ...1.... (0x22110)
= ......b. ..f....a ...e....
第二个是:
........ ........ abcdefgh
* ........ 1....... ..1..... (0x8020)
= .abcdefg h..abcde fgh.....
& ....1... 1....1.. .1...... (0x88440)
= ....d... h....c.. .g......
将它们组合并乘以最终常数得出:
......b. ..f....a ...e....
| ....d... h....c.. .g......
= ....d.b. h.f..c.a .g.e....
* .......1 .......1 .......1 (0x10101)
= ....d.b. h.f..c.a .g.e....
+h.f..c.a .g.e.... ........
+.g.e.... ........ ........
= hgfedcba hgfe.c.a .g.e....
最后向下移动16位得到hgfedcba
,与原始模式相反。
答案 1 :(得分:6)
从这个问题:Best Algorithm for Bit Reversal ( from MSB->LSB to LSB->MSB) in C
似乎正在扭转比特。
0010 0000 => 0000 0100
答案 2 :(得分:3)