Eine etwas knappere Antwort:
AAAAAAAA G HHHHHH
Verpacken:
packed = age << 8 | gender << 7 | height
Alternativ können Sie auch nur die Komponenten addieren, d.h. wenn Sie die MySQL SUM Aggregatfunktion verwenden
packed = age << 8 + gender << 7 + height
Auspacken:
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
Ein anderes (längeres) Beispiel:
Angenommen, Sie haben eine IP-Adresse, die Sie verpacken möchten, aber es ist eine fiktive IP-Adresse, z. B. 132.513.151.319. Beachten Sie, dass einige Komponenten größer als 256 sind, was im Gegensatz zu echten IP-Adressen mehr als 8 Bits erfordert.
Zuerst müssen wir herausfinden, welchen Offset wir verwenden müssen, um die maximale Anzahl zu speichern. Nehmen wir an, mit unseren fiktiven IPs kann keine Komponente größer als 999 sein, was bedeutet, dass wir 10 Bits Speicherplatz pro Komponente benötigen (erlaubt Zahlen bis zu 1014).
packed = (comp1 << 0 * 10) | (comp1 << 1 * 10) | (comp1 << 2 * 10) | (comp1 << 3 * 10)
Das gibt dec 342682502276
o bin 100111111001001011110000000010010000100
Packen wir nun den Wert aus
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
Wo (1 << 10) - 1
ist eine binäre Maske, mit der wir die Bits auf der linken Seite jenseits der 10 Bits auf der rechten Seite ausblenden, an denen wir interessiert sind.
Gleiches Beispiel mit MySQL-Abfrage
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`;