我在一些旧的和错误的 C 代码中发现了以下内容:
#define addr (((((147 << 8) | 87) << 8) | 117) << 8) | 107
它是什么?好吧,我知道这是一个 IP 地址 - 向左移动 8 位也很有意义。但是任何人都可以向我解释这个整体吗?那里发生了什么?
谢谢!
编码
(((((147 << 8) | 87) << 8) | 117) << 8) | 107
生成包含 IP 147.87.117.107 的 4 个字节。第一步是最里面的括号:
147<<8
147 = 1001 0011
1001 0011 << 8 = 1001 0011 0000 0000
第二个字节 87 通过 (147<<8) 上的按位或操作插入。如您所见,右边的 8 位都是 0(由于 <<8),所以按位或运算只是插入 87 中的 8 位:
1001 0011 0000 0000 (147<<8)
0000 0000 0101 0111 (87)
------------------- bitwise-or
1001 0011 0101 0111 (147<<8)|87
其余部分也是如此,因此最后将 4 个字节保存到一个 32 位整数中。
IPv4 地址由四个字节组成,这意味着它可以存储在 32 位整数中。这是采用 IP 地址 (147.87.117.107) 的四个部分并使用位移和按位 OR 运算符将地址“编码”为单个 4 字节数量。
(注意:地址可能是 107.117.87.147 - 我不记得字节的存储顺序。)
结果数量的(十六进制)字节如下所示:
aabb ccdd
其中aa是147(0x93)的十六进制表示,bb是87(0x57),cc是117(0x75),dd是107(0x6b),所以得到的值是9357756b。
更新:这些都不适用于 IPv6,因为 IPv6 地址是 128 位而不是 32 位。