10

ビットを表す 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
4

5 に答える 5

11

コードは最初のビットを単語の下位ビットとして扱っているため、各単語が逆になります。簡単な修正として、これを試してください:

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

これにより、配列の最初のビットが最初のバイトの最上位に配置されます。

于 2009-04-05T20:09:11.057 に答える
7
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);
于 2009-04-05T20:13:14.107 に答える
5

それを自動的に行う方法があるかどうかはわかりませんが、単純なアルゴリズムで行うことができます。

単純なアルゴリズム:

  1. 出力バッファとして使用されるバイト配列を作成し、すべてのバイトを 0 に初期化します。この配列のサイズは、入力ブール配列の長さに基づく必要があります: ceil(bool_array_length / 8.0)

  2. 現在のバイトとして使用するインデックス変数を宣言し、それを 0 に設定します。これにより、出力バッファーにインデックスが保持されます。

  3. 入力ブール配列の各要素を反復処理します。
    3.1. 数値 1 を配列インデックス mod 8 だけ左ビット シフトします。この数値をマスクと呼びます。
    3.2. 配列 div 8 への現在のインデックスとして、バイト インデックスを計算します
    true入力ブール配列の現在のインデックスにブール値がある場合はbitwise OR、現在のバイトとマスクを使用して a を実行します。

于 2009-04-05T19:25:35.890 に答える
1
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();
}
于 2013-08-30T10:18:21.850 に答える
1

この関数 (拡張メソッドとして記述) を試してください。

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;
}

注:ビット数(ブール値)が8の倍数でない場合は失敗しますが、質問から判断するとそうではありません。任意の長さのビット配列を許可するには、非常に小さな変更しか必要ありません。

于 2009-04-05T20:12:35.183 に答える