题
我有一个由 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));
这使第一比特阵列中的第一个字节,等等的最高位置。
其他提示
我不知道是否有自动的方法来做到这一点,但你可以用一个简单的算法来做到这一点。
简单的算法:
创建一个将用作输出缓冲区的字节数组,并将所有字节初始化为 0。该数组的大小应基于输入布尔数组的长度:ceil(布尔数组长度/8.0)
声明一个索引变量用作当前字节,并将其设置为 0。这将索引保存在输出缓冲区中。
迭代输入布尔数组中的每个元素。
3.1.将数字 1 左移数组索引 mod 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);
尝试该功能(写为扩展方法)。
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的倍数,但是您的问题来看不是这种情况下,它将会失败。这将只需要一个非常小的modificaiton以允许任意长度的比特列。
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();
}
不隶属于 StackOverflow