Как я могу преобразовать биты в байты? - PullRequest
9 голосов
/ 05 апреля 2009

У меня есть массив из 128 логических значений, которые представляют биты. Как я могу преобразовать эти 128-битные представления в 16 байтов?

Пример:

У меня есть массив, который выглядит следующим образом:

0110001100110000100010111011001011010011010001010001101101001100
1000010000000000001000111111111101000011111001111011111011111001

(преобразовано в 1 и 0, чтобы быть более кратким)

Мне нужно преобразовать эти биты в следующий байтовый массив:

99 48 139 178 211 69 27 76 132 0 35 255 67 231 190 249

РЕДАКТИРОВАТЬ: Это не похоже на работу:

public byte[] ToByteArray() {
    int numBytes = Count / 8;

    if (_bits.Count % 8 != 0) numBytes++;

    byte[] bytes = new byte[numBytes];

    int byteIndex = 0, bitIndex = 0;

    for (int i = 0; i < _bits.Count; i++) {
        if (_bits[i])
            bytes[byteIndex] |= (byte)(1 << bitIndex);

        bitIndex++;
        if (bitIndex == 8) {
            bitIndex = 0;
            byteIndex++;
        }
    }

    return bytes;
}

Выводит:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159

Ответы [ 5 ]

10 голосов
/ 06 апреля 2009

Код обрабатывает первый бит как младший бит слова, так что вы в конечном итоге получаете каждое слово в обратном порядке. В качестве быстрого и грязного исправления попробуйте следующее:

bytes[byteIndex] |= (byte)(1 << (7-bitIndex));

Это помещает первый бит в массиве в верхнюю позицию в первом байте и т. Д.

5 голосов
/ 05 апреля 2009

Я не знаю, есть ли автоматический способ сделать это, но вы можете сделать это с помощью простого алгоритма.

Простой алгоритм:

  1. Создайте массив байтов, который будет использоваться в качестве выходного буфера, и инициализируйте все байты равными 0. Размер этого массива должен основываться на длине вашего входного логического массива: ceil (bool_array_length / 8.0)

  2. Объявите индексную переменную, которая будет использоваться в качестве текущего байта, и установите для нее значение 0. Он содержит индекс в вашем выходном буфере.

  3. Перебирать каждый элемент во входном логическом массиве.
    3.1. Левый бит сдвигает число 1 на индекс индекса массива 8. Назовите этот номер своей маской.
    3.2. Рассчитайте свой байтовый индекс как текущий индекс в массиве div 8.
    3.3. Если у вас есть логическое значение true текущего индекса во входном логическом массиве, выполните bitwise OR с вашим текущим байтом и маской.

4 голосов
/ 06 апреля 2009
bool[] bools = ...
BitArray a = new BitArray(bools);
byte[] bytes = new byte[a.Length / 8];
a.CopyTo(bytes, 0);

РЕДАКТИРОВАТЬ: На самом деле это также возвращает:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159

Неправильный порядок байтов? Я все равно оставлю ответ, для справки.


РЕДАКТИРОВАТЬ: Вы можете использовать BitArray.CopyTo (), обращая массивы следующим образом:

bool[] bools = ...
Array.Reverse(bools); // NOTE: this modifies your original array
BitArray a = new BitArray(bools);
byte[] bytes = new byte[a.Length / 8];
a.CopyTo(bytes, 0);
Array.Reverse(bytes);
1 голос
/ 30 августа 2013
private static byte[] GetBytes(string bitString)
{
    byte[] result = Enumerable.Range(0, bitString.Length / 8).
        Select(pos => Convert.ToByte(
            bitString.Substring(pos * 8, 8),
            2)
        ).ToArray();

    List<byte> mahByteArray = new List<byte>();
    for (int i = result.Length - 1; i >= 0; i--)
    {
        mahByteArray.Add(result[i]);
    }

    return mahByteArray.ToArray();
}

private static String ToBitString(BitArray bits)
{
    var sb = new StringBuilder();

    for (int i = bits.Count - 1; i >= 0; i--)
    {
        char c = bits[i] ? '1' : '0';
        sb.Append(c);
    }

    return sb.ToString();
}
1 голос
/ 06 апреля 2009

Попробуйте эту функцию (записывается как метод расширения).

public byte[] ToByteArray(this bool[] bits)
{
    var bytes = new byte[bits.Length / 8];
    for (int i = 0, j = 0; j < bits.Length; i++, j += 8)
    {
        // Create byte from bits where LSB is read first.
        for (int offset = 0; offset < 8; offset++)
            bytes[i] |= (bits[j + offset] << offset);
    }

    return bytes;
}

Примечание: произойдет сбой, если число битов (bools) не кратно 8, но, судя по вашему вопросу, это не так. Для разрешения битовых массивов любой длины потребуется лишь очень небольшая модификация.

...