На вход поступает какой-то файл (не важно какой). Мне необходимо упаковать
8-битные байты в 6-битные. Т.е. поступило 3 8-битных байта (10101000 00001111 01011010), преобразуем их в следующее: 101010 000000 111101 011010.
Я пробовал сделать это с помощью строк (представление числа в виде строки 0 и 1, а потом нарезка этих строк), но данный подход не эффективен. Остаются побитовые операции. Но в этом случае я не разобрался с тем, как нарезать байты. (каждый раз маска меняется: для первого раза, чтобы отсечь 6 старших бит нужна такая (11111100), два младших бита перекочевывают в другой байт, и становятся в нем старшими, для второго раза нам нужно отсечь уже 4 старших бита, ведь 2 уже пришли из другого байта, и маска становится такой (11110000).
Мне не нужен код, я хочу лишь алгоритм.
Вот такой код в меня получился на C#. Алгоритм вы поймете, я добавил комментарии.
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)));
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости