2009-04-05 52 views
9

Tôi có một mảng 128 boolean đại diện cho bit. Làm thế nào tôi có thể chuyển đổi các đại diện 128 bit thành 16 byte?Làm cách nào để chuyển đổi bit thành byte?

Ví dụ:

Tôi có một mảng mà trông như thế này:

0110001100110000100010111011001011010011010001010001101101001100 
1000010000000000001000111111111101000011111001111011111011111001 

(Chuyển Đổi Sang 1s và 0s là ngắn gọn hơn)

tôi cần phải chuyển đổi những bit như sau mảng byte:

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

EDIT: Điều này dường như không hoạt động:

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

Nó ra:

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

Bạn có thể loại bỏ các biến 'byteIndex' bằng công (%) điều hành modulo. byte [bitIndex% 8] – arul

+0

@arul, tôi nghi ngờ bạn đang nghĩ đến phân chia số nguyên. Modulo sẽ phải được sử dụng ở phía bên phải của nhiệm vụ. 'bytes [bitIndex/8] | = (byte) (1 << (bitIndex% 8))' –

Trả lời

10

Mã này xử lý bit đầu tiên làm bit thấp của từ, vì vậy bạn kết thúc với mỗi từ bị đảo ngược. Là một sửa chữa nhanh chóng-và-bẩn, hãy thử này:

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

Điều đó đặt bit đầu tiên trong mảng tại vị trí cao nhất trong byte đầu tiên, vv

+0

Tuyệt vời, cảm ơn! –

5

Tôi không biết nếu có một cách tự động để làm điều đó, nhưng bạn có thể làm điều đó với một thuật toán đơn giản.

đơn giản thuật toán:

  1. Tạo một mảng byte sẽ được sử dụng như đệm đầu ra của bạn, và khởi tạo tất cả các byte để 0. Kích thước của mảng này nên được dựa vào độ dài của bạn mảng boolean đầu vào: ceil (bool_array_length/8.0)

  2. Khai báo biến chỉ mục sẽ được sử dụng làm byte hiện tại của bạn và đặt nó thành 0. Điều này giữ chỉ mục trong bộ đệm đầu ra của bạn.

  3. Lặp lại từng phần tử trong mảng boolean đầu vào của bạn.
    3.1. Bit bên trái dịch chuyển số 1 bằng chỉ số mảng mod 8. Gọi số này là mặt nạ của bạn.
    3.2. Tính chỉ số byte của bạn làm chỉ mục hiện tại của bạn thành mảng div 8.
    3.3. Nếu bạn có giá trị boolean true giá trị hiện tại trong mảng boolean đầu vào của bạn, hãy thực hiện bitwise OR với byte hiện tại và mặt nạ của bạn.

1

Hãy thử chức năng này (viết như một phần mở rộng phương pháp).

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

Lưu ý: Số bit (bools) không phải là bội số của 8, nhưng đánh giá bởi câu hỏi của bạn không phải như vậy. Nó sẽ chỉ mất một modificaiton rất nhỏ để cho phép mảng bit của bất kỳ chiều dài.

+0

bạn có nghĩa là "byte [i] | = (bit [j + bù đắp] << bù đắp)"? – Lucas

+0

Vâng, tất nhiên rồi. Vâng phát hiện. – Noldorin

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

EDIT: Thực ra điều này cũng trả về:

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

endianness sai? Tôi sẽ để lại câu trả lời anyway, để tham khảo.


EDIT: Bạn có thể sử dụng BitArray.CopyTo() bằng cách đảo ngược các mảng như vậy:

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(); 
} 
Các vấn đề liên quan