如何将位转换为字节?

我有一个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。 左位通过数组索引mod将数字1移位8.将此数字称为掩码。
    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); 

试试这个function(作为扩展方法编写)。

 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 mahByteArray = new List(); 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(); }