Created
November 20, 2021 17:38
-
-
Save xeoncross/19ae1519d7376489e21357f97eab678a to your computer and use it in GitHub Desktop.
store a list of 6bit values in a regular 8bit byte array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I'm playing with compression using dictionaries (for learning) and needed to figure out the logic for when saving 6 bits across two different byte boundaries. Basically, when storing multiple 6 bit values in regular 8 bit bytes, how do you calculate the bit shifting needed to split the bits up between different bytes in the []byte slice? | |
https://goplay.space/#dfgOt3sGJzN | |
*/ | |
func TestManualBytes(t *testing.T) { | |
// | |
// Demo 1: manual | |
// | |
data := []byte{0, 0, 0} | |
// store this value using only 6 bits | |
value := uint8(31) // [00]011111 | |
data[0] |= value << 2 | |
// 011111.. | |
// first 2 bits on byte[0], next 4 on byte[1] | |
data[0] |= value >> 4 | |
data[1] |= value << 4 | |
// 01111101 1111.... | |
// first 4 bits on byte[1], next 2 on byte[2] | |
data[1] |= value >> 2 // first bit | |
data[2] |= value << 6 | |
// // 01111101 11110111 11...... | |
fmt.Printf("data: %08b\n", data) | |
// | |
// Demo 2: based on position | |
// | |
data = []byte{0, 0, 0} | |
pos := 0 | |
data[pos/8] |= value << 2 | |
pos += 6 | |
// 011111.. | |
// first 2 bits on byte[0], next 4 on byte[1] | |
data[pos/8] |= value >> 4 | |
pos += 2 | |
data[pos/8] |= value << 4 | |
pos += 4 | |
// 01111101 1111.... | |
// first 4 bits on byte[1], next 2 on byte[2] | |
data[pos/8] |= value >> 2 // first bit | |
pos += 4 | |
data[pos/8] |= value << 6 | |
pos += 2 | |
// // 01111101 11110111 11...... | |
fmt.Printf("data: %08b\n", data) | |
// | |
// Demo 3: Automatted | |
// | |
const ( | |
packetSize = 6 | |
byteSize = 8 | |
) | |
data = []byte{0, 0, 0} | |
pos = 0 | |
for i := 0; i < 4; i++ { | |
idx := pos / byteSize | |
bitsRem := byteSize - (pos % byteSize) | |
shift := bitsRem - packetSize | |
if shift < 0 { | |
data[idx] |= value >> (-1 * shift) | |
shift = byteSize + shift | |
idx = idx + 1 | |
} | |
data[idx] |= value << shift | |
pos += packetSize | |
} | |
fmt.Printf("data: %08b\n", data) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment