2011-12-13 65 views
13

我正在使用一些遗留代码,并且我遇到了一个显然用于在任意长字段(大于ntohl可以处理的字段)上执行网络字节顺序转换的函数。这实际上是做什么的? - 疯狂的C++函数

虽然(或者即使它可以可靠地做到这一点),但我不能很好地理解它是否做了比在msg缓冲区范围内颠倒字节顺序更多的事情。有人可以帮我解决这个问题,并分析它,所以我可以用更容易理解的东西来取代它(或者至少评论它)!

void swapit(unsigned char *msg, int length) { 
    for(;length>0;length--, msg++) { 
    *msg = ((*msg * 0x0802LU & 0x22110LU) | 
      (*msg * 0x8020LU & 0x88440LU)) * 
      0x10101LU >> 16; 
    } 
} 
+3

请参阅http://stackoverflow.com/a/746203/367273其中此功能与许多选择一起出现。投票在此基础上结束。 – NPE

+0

呃......我应该把它当作“它是完全安全的,不用担心吗?” –

+1

这取决于你。它显然值得一个评论(也许是另一个SO问题的链接:-)) – NPE

回答

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,与原始模式相反。

+0

感谢您的详细解答,它使它更容易理解:) –

相关问题