假设:
转换 byte []从Little Endian到Big Endian意味着反转位的顺序 字节[]的每个字节。
假设这是正确的,我尝试了以下内容来理解这一点:
byte[] data = new byte[] { 1, 2, 3, 4, 5, 15, 24 };
byte[] inverted = ToBig(data);
var little = new BitArray(data);
var big = new BitArray(inverted);
int i = 1;
foreach (bool b in little)
{
Console.Write(b ? "1" : "0");
if (i == 8)
{
i = 0;
Console.Write(" ");
}
i++;
}
Console.WriteLine();
i = 1;
foreach (bool b in big)
{
Console.Write(b ? "1" : "0");
if (i == 8)
{
i = 0;
Console.Write(" ");
}
i++;
}
Console.WriteLine();
Console.WriteLine(BitConverter.ToString(data));
Console.WriteLine(BitConverter.ToString(ToBig(data)));
foreach (byte b in data)
{
Console.Write("{0} ", b);
}
Console.WriteLine();
foreach (byte b in inverted)
{
Console.Write("{0} ", b);
}
转换方法:
private static byte[] ToBig(byte[] data)
{
byte[] inverted = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
{
var bits = new BitArray(new byte[] { data[i] });
var invertedBits = new BitArray(bits.Count);
int x = 0;
for (int p = bits.Count - 1; p >= 0; p--)
{
invertedBits[x] = bits[p];
x++;
}
invertedBits.CopyTo(inverted, i);
}
return inverted;
}
这个小应用程序的输出与我的预期不同:
00000001 00000010 00000011 00000100 00000101 00001111 00011000
00000001 00000010 00000011 00000100 00000101 00001111 00011000
80-40-C0-20-A0-F0-18
01-02-03-04-05-0F-18
1 2 3 4 5 15 24
1 2 3 4 5 15 24
由于某种原因,数据保持不变,除非使用BitConverter打印。
我不理解什么?
更新
新代码产生以下输出:
10000000 01000000 11000000 00100000 10100000 11110000 00011000
00000001 00000010 00000011 00000100 00000101 00001111 00011000
01-02-03-04-05-0F-18
80-40-C0-20-A0-F0-18
1 2 3 4 5 15 24
128 64 192 32 160 240 24
但正如我现在被告知的那样,我的方法无论如何都是错误的,因为我应该反转字节 而不是位?
我正在使用的这位硬件开发人员告诉我要反转这些位,因为他无法读取数据。
我正在使用此
的上下文使用它的应用程序并不适用于数字。
我应该将一串位保存到文件
1 =白色,0 =黑色。
它们表示位图256x64的像素。
字节0到字节31表示第一行像素 字节32到字节63第二行像素。
我有输出这些位的代码......但是开发人员在说 我他们的顺序错了......他说字节很好,但不是。
所以我感到困惑:p
答案 0 :(得分:6)
没有。字节顺序是指字节的顺序,而不是位。大端系统首先存储最重要的字节,而小端系统首先存储最不重要的字节。一个字节内的位保持相同的顺序。
你的ToBig()函数正在返回原始数据而不是位交换数据。
答案 1 :(得分:2)
此时您的方法可能正确。字节序有不同的含义,它取决于硬件。
通常,它用于在计算平台之间进行转换。对于不同的芯片组,大多数CPU供应商(现在)使用相同的位排序,但字节排序不同。这意味着,如果您将一个2字节的int从一个系统传递到另一个系统,则只保留位,但交换字节1和2,即:
int somenumber -> byte[2]: somenumber[high],somenumber[low] ->
byte[2]: somenumber[low],somenumber[high] -> int newNumber
但是,并非总是如此。有些硬件仍然使用倒BIT排序,所以你所拥有的可能是正确的。您需要信任您的硬件开发人员。或进一步研究。
我建议在维基百科上阅读这篇文章 - 始终是一个很好的信息来源:
http://en.wikipedia.org/wiki/Endianness
你的ToBig方法有一个错误。
最后:
invertedBits.CopyTo(data, i);
}
return data;
您需要将其更改为:
byte[] newData = new byte[data.Length];
invertedBits.CopyTo(newData, i);
}
return newData;
您正在重置输入数据,因此您将同时接收两个阵列。问题是数组是引用类型,因此您可以修改原始数据。
答案 2 :(得分:2)
正如greyfade已经说过的那样,字节顺序与位排序无关。
您的代码没有达到预期效果的原因是ToBig方法更改了您发送给它的数组。这意味着在调用方法之后,数组被反转,而data
和inverted
只是指向同一数组的两个引用。
这是该方法的更正版本。
private static byte[] ToBig(byte[] data) {
byte[] result = new byte[data.length];
for (int i = 0; i < data.Length; i++) {
var bits = new BitArray(new byte[] { data[i] });
var invertedBits = new BitArray(bits.Count);
int x = 0;
for (int p = bits.Count - 1; p >= 0; p--) {
invertedBits[x] = bits[p];
x++;
}
invertedBits.CopyTo(result, i);
}
return result;
}
编辑:
这是一个改变字节数组的字节顺序的方法:
static byte[] ConvertEndianness(byte[] data, int wordSize) {
if (data.Length % wordSize != 0) throw new ArgumentException("The data length does not divide into an even number of words.");
byte[] result = new byte[data.Length];
int offset = wordSize - 1;
for (int i = 0; i < data.Length; i++) {
result[i + offset] = data[i];
offset -= 2;
if (offset < -wordSize) {
offset += wordSize * 2;
}
}
return result;
}
示例:
byte[] data = { 1,2,3,4,5,6 };
byte[] inverted = ConvertEndianness(data, 2);
Console.WriteLine(BitConverter.ToString(inverted));
输出:
02-01-04-03-06-05
第二个参数是单词大小。由于字节顺序是单词中字节的顺序,因此您必须指定单词的大小。
编辑2:
这是一种更有效的反转位的方法:
static byte[] ReverseBits(byte[] data) {
byte[] result = new byte[data.Length];
for (int i = 0; i < data.Length; i++) {
int b = data[i];
int r = 0;
for (int j = 0; j < 8; j++) {
r <<= 1;
r |= b & 1;
b >>= 1;
}
result[i] = (byte)r;
}
return result;
}
答案 3 :(得分:0)
我看到的一个大问题是ToBig更改了传递给它的data[]
数组的内容。
您在名为data
的数组上调用ToBig,然后将结果分配给inverted
,但由于您没有在ToBig中创建新数组,因此您修改了两个数组,然后继续将数组data
和inverted
视为不同,而实际上并非如此。