Packing standard bytes (8 bits) into 6 bits

The input is a file (it doesn't matter which one). I need to pack 8-bit bytes to 6-bit bytes. That is, we received 3 8-bit bytes (10101000 00001111 01011010), we convert them to the following: 101010 000000 111101 011010.

I tried to do this using strings (representing a number as a string of 0 and 1, and then slicing these strings), but this approach is not effective. Bitwise operations remain. But in this case, I didn't figure out how to slice the bytes. (each time the mask changes: for the first time, to to cut off the 6 highest bits, we need this (11111100), the two lowest bits migrate to another byte, and become the highest in it, for the second time we need to cut off the 4 highest bits, because 2 have already come from another byte, and the mask becomes this (11110000).

I don't need the code, I just want the algorithm.

Author: Kromster, 2018-08-17

1 answers

This is the code I got in C#. You will understand the algorithm, I added comments.

byte[] array = new byte[]
{
    Convert.ToByte("10101000", 2),
    Convert.ToByte("00001111", 2),
    Convert.ToByte("01011010", 2),
};
int cut = 6; // на сколько бит резать

List<byte> result = new List<byte>();
int remainder = 0; // остаток
int remBits = 0;   // сколько бит в остатке
for (int i = 0; i < array.Length; i++)
{
    remainder = (remainder << 8) | array[i]; // добавляем в остаток следующий байт
    remBits += 8; // количество бит в остатке увеличиваем на длину байта
    while (remBits >= cut) // пока в остатке остается кусок, который мы может вырезать
    {
        result.Add((byte)(remainder >> (remBits - cut))); // берем старшие cut бит
        remainder &= (1 << (remBits - cut)) - 1; // обнуляем их

        remBits -= cut; // вычитаем биты из остатка
    }
}

if (remBits > 0) // если что то осталось (например, если нельзя нацело разделить), добавляем то, что осталось
    result.Add((byte)(remainder << (cut - remBits)));
 1
Author: Zergatul, 2018-08-18 10:39:24