문제

비트를 나타내는 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
도움이 되었습니까?

해결책

코드는 첫 번째 비트를 단어의 낮은 비트로 취급하므로 각 단어가 반대로됩니다. 빠른 수정으로 다음을 시도하십시오.

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

첫 번째 바이트에서 첫 번째 비트를 배열에서 가장 높은 위치에 놓습니다.

다른 팁

자동으로 할 수있는 방법이 있는지 모르겠지만 간단한 알고리즘으로 수행 할 수 있습니다.

간단한 알고리즘 :

  1. 출력 버퍼로 사용될 바이트 배열을 만들고 모든 바이트를 0으로 초기화합니다.이 배열의 크기는 입력 부울 배열의 길이를 기준으로해야합니다 : CEIL (bool_array_length / 8.0).

  2. 현재 바이트로 사용할 인덱스 변수를 선언하고 0으로 설정하십시오. 출력 버퍼의 인덱스를 보유합니다.

  3. 입력 부울 배열의 각 요소를 반복하십시오.
    3.1. 왼쪽 비트 배열 인덱스 모드에 의해 숫자 1을 이동합니다.이 번호를 마스크로 호출하십시오.
    3.2. 배열 DIV 8의 현재 색인으로 바이트 색인을 계산하십시오.
    3.3. 부울이 있다면 true 입력 부울 배열에서 현재 인덱스를 평가하십시오. bitwise OR 현재 바이트와 마스크로.

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

이 기능을 시도하십시오 (확장 방법으로 작성).

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

참고 : 비트 수 (bool)가 8의 배수가 아닌 경우에는 실패합니다. 그러나 귀하의 질문에 따라 판단하는 것은 그렇지 않습니다. 길이의 비트 어레이를 허용하기 위해서는 매우 작은 변형이 필요합니다.

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();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top