2009-04-05 11 views
9

Mam tablicę 128 bajtów reprezentujących bity. Jak mogę przekonwertować te reprezentacje 128-bitowe na 16 bajtów?Jak mogę przekonwertować bity na bajty?

przykład:

mam tablicę, która wygląda następująco:

0110001100110000100010111011001011010011010001010001101101001100 
1000010000000000001000111111111101000011111001111011111011111001 

(Konwersja do 1 i 0 są bardziej zwięzły)

trzeba przekształcić te bity do następujących tablica bajtów:

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

EDIT: To nie wydaje się działać:

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

To Wyjścia:

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

można wyeliminować zmienną 'byteIndex' stosując (%) operatora modulo. bajtów [bitIndex% 8] – arul

+0

@arul, podejrzewam, że myślałeś o podziałach całkowitych. Modulo będzie musiał być użyty po prawej stronie zadania. 'bajty [bitIndex/8] | = (bajt) (1 << (bitIndex% 8))' –

Odpowiedz

10

Kod traktuje pierwszy bit jako dolny bit słowa, więc kończy się każdym odwróconym słowem. Jako szybki i brzydka fix, spróbuj tego:

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

To stawia pierwszy bit w tablicy na najwyższej pozycji w pierwszym bajcie, itp

+0

Niesamowite, dziękuję! –

5

Nie wiem, czy istnieje automatyczny sposób to zrobić, ale można to zrobić za pomocą prostego algorytmu.

prosty algorytm:

  1. Utwórz tablicę bajtów, które będą używane jako bufora wyjściowego i zainicjować wszystkich bajtów 0. Wielkość tej tablicy powinny być oparte na długość wejście tablica logiczna: ceil (bool_array_length/8,0)

  2. Zadeklaruj zmienną indeksu, który będzie używany jako bieżący bajt, i ustawić go na 0. posiada indeks w swoim buforze wyjściowym.

  3. Powtórz poszczególne elementy tablicy wprowadzania danych.
    3.1. Lewe przesunięcie bitowe liczby 1 przez indeks tablicowy mod 8. Nazwij ten numer swoją maską.
    3.2. Oblicz swój indeks bajtowy jako bieżący indeks w tablicy div 8.
    3.3. Jeśli masz wartość boolowską true wartość bieżącego indeksu w tablicy danych wejściowych, wykonaj bitwise OR z bieżącym bajtem i maską.

1

Spróbuj tej funkcji (napisany jako rozszerzenie metoda).

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

Uwaga: To nie powieść, jeśli liczba bitów (bools) nie jest wielokrotnością 8, ale sądząc po twoim pytaniu nie jest to przypadek. Wystarczyłaby niewielka modyfikacja, aby umożliwić tablice bitowe dowolnej długości.

+0

miałeś na myśli "bytes [i] | = (bity [j + offset] << offset)"? – Lucas

+0

Tak, oczywiście. Dobrze zauważony. – Noldorin

4
bool[] bools = ... 
BitArray a = new BitArray(bools); 
byte[] bytes = new byte[a.Length/8]; 
a.CopyTo(bytes, 0); 

EDIT: Właściwie to zwraca również:

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

Błędna endianness? I tak zostawię odpowiedź, dla odniesienia.


Edycja: Można użyć BitArray.CopyTo() przez zmianę tablic tak:

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
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(); 
} 
Powiązane problemy