更简洁的答案:
啊啊啊啊啊啊啊啊啊啊
包装:
packed = age << 8 | gender << 7 | height
或者,如果在 MySQL SUM 聚合函数中使用时,您可以只对组件求和
packed = age << 8 + gender << 7 + height
开箱:
age = packed >> 8 // no mask required
gender = packed >> 7 & ((1 << 1) - 1) // applying mask (for gender it is just 1)
height = packed & ((1 << 7) - 1) // applying mask
另一个(更长的)示例:
假设您有一个要打包的 IP 地址,但它是一个虚构的 IP 地址,例如 132.513.151.319。请注意,某些大于 256 的组件需要超过 8 位,这与真实 IP 地址不同。
首先,我们需要弄清楚我们需要使用什么偏移量才能存储最大数量。假设我们虚构的 IP 没有任何组件可以大于 999,这意味着我们每个组件需要 10 位存储(最多允许 1014 个数字)。
packed = (comp1 << 0 * 10) | (comp1 << 1 * 10) | (comp1 << 2 * 10) | (comp1 << 3 * 10)
哪个给出dec 342682502276
或bin 100111111001001011110000000010010000100
现在让我们解压值
comp1 = (packed >> 0 * 10) & ((1 << 10) - 1) // 132
comp2 = (packed >> 1 * 10) & ((1 << 10) - 1) // 513
comp3 = (packed >> 2 * 10) & ((1 << 10) - 1) // 151
comp4 = (packed >> 3 * 10) & ((1 << 10) - 1) // 319
(1 << 10) - 1
我们用来隐藏我们感兴趣的最右边 10 位之外的左侧位的二进制掩码在哪里。
使用 MySQL 查询的相同示例
SELECT
(@offset := 10) AS `No of bits required for each component`,
(@packed := (132 << 0 * @offset) |
(513 << 1 * @offset) |
(151 << 2 * @offset) |
(319 << 3 * @offset)) AS `Packed value (132.513.151.319)`,
BIN(@packed) AS `Packed value (bin)`,
(@packed >> 0 * @offset) & ((1 << @offset) - 1) `Component 1`,
(@packed >> 1 * @offset) & ((1 << @offset) - 1) `Component 2`,
(@packed >> 2 * @offset) & ((1 << @offset) - 1) `Component 3`,
(@packed >> 3 * @offset) & ((1 << @offset) - 1) `Component 4`;