如何将一个整数转换为小端字节数组?

33

我在C#中有这个函数,用于将小端字节数组转换为整数:

int LE2INT(byte[] data)
{
  return (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
}

现在我想将它转换回小端序。 类似这样:

byte[] INT2LE(int data)
{
  // ...
}

有什么想法吗?

谢谢。

9个回答

33

您可以使用BitConverter类来完成此操作,当然,它也可以在小端和大端系统上使用。

当然,您需要跟踪数据的字节序(即“大小端”)。例如,在通信中,这将在协议中定义。

然后,您可以使用BitConverter类将数据类型转换为字节数组,反之亦然,然后使用IsLittleEndian标志查看是否需要在您的系统上进行转换。

IsLittleEndian标志将告诉您系统的字节序,因此您可以按以下方式使用它:

这是来自BitConverter类的MSDN页面上的内容。

  int value = 12345678; //your value
  //Your value in bytes... in your system's endianness (let's say: little endian)
  byte[] bytes = BitConverter.GetBytes(value);
  //Then, if we need big endian for our protocol for instance,
  //Just check if you need to convert it or not:
  if (BitConverter.IsLittleEndian)
     Array.Reverse(bytes); //reverse it so we get big endian.

您可以在此处找到完整的文章。

希望这能帮助到来到这里的任何人 :)


26

只需颠倒它,请注意此代码(就像其他代码一样)仅适用于小端机器。(编辑 - 这是错误的,因为此代码根据定义返回LE)

  byte[] INT2LE(int data)
  {
     byte[] b = new byte[4];
     b[0] = (byte)data;
     b[1] = (byte)(((uint)data >> 8) & 0xFF);
     b[2] = (byte)(((uint)data >> 16) & 0xFF);
     b[3] = (byte)(((uint)data >> 24) & 0xFF);
     return b;
  }

6
为什么你的示例只能在小端机器上工作?据我所知,位移方法应该与字节序无关。 - nonoitall
@John,我非常确定你的代码无论在大端还是小端架构上运行都可以正常工作。在任何情况下,b [0]都是最低位字节,b [1]是次低位字节,依此类推。 - Dale Hagglund
我的错误,因为这段代码返回LE而不是底层CPU的自然字节顺序,所以它将在所有架构上工作。我会删除不正确的文本。 - John Knoeller
2
根据ECMA-335标准,从uint转换为byte(指令conv.i1)意味着简单地将最高有效字节清零。因此,“&0xFF”部分是多余的。 - SLenik

8

反过来做就可以了:

result[3]= (data >> 24) & 0xff;
result[2]= (data >> 16) & 0xff;
result[1]= (data >> 8)  & 0xff;
result[0]=  data        & 0xff; 

3

您可以使用BitConverter类吗?我认为它只适用于小端硬件,但它应该可以处理大部分繁重的工作。

以下是一个编造的示例,演示了该类的使用:

if (BitConverter.IsLittleEndian)
{
    int someInteger = 100;
    byte[] bytes = BitConverter.GetBytes(someInteger);
    int convertedFromBytes = BitConverter.ToInt32(bytes, 0);
}

2
BitConverter.GetBytes(1000).Reverse<byte>().ToArray();

1
请问您能否解释一下为什么这会有帮助? - John Odom
我非常确定这是针对大端机的情况。 - Vassilis

1
尝试使用位于 System.Buffers.Binary 中的BinaryPrimitives,它提供了读写所有 .net 原始类型的帮助方法,支持小端和大端形式。
byte[] IntToLittleEndian(int data)
{
  var output = new byte[sizeof(int)];
  BinaryPrimitives.WriteInt32LittleEndian(output, data);
  return output;
}

int LittleEndianToInt(byte[] data)
{
  return BinaryPrimitives.ReadInt32LittleEndian(data);
}

1

根据你实际的操作,你可以依赖于让框架处理字节序的细节,通过使用IPAddress.HostToNetworkOrder和相应的反转函数。然后只需使用BitConverter类来在字节数组之间进行转换。


0
 public static string decimalToHexLittleEndian(int _iValue, int _iBytes)
    {
        string sBigEndian = String.Format("{0:x" + (2 * _iBytes).ToString() + "}", _iValue);
        string sLittleEndian = "";

        for (int i = _iBytes - 1; i >= 0; i--)
        {
            sLittleEndian += sBigEndian.Substring(i * 2, 2);
        }

        return sLittleEndian;
    }

0

如果您不想使用新的堆分配,可以使用此选项:

public static void Int32ToFourBytes(Int32 number, out byte b0, out byte b1, out byte b2, out byte b3)
{
    b3 = (byte)number;
    b2 = (byte)(((uint)number >> 8) & 0xFF);
    b1 = (byte)(((uint)number >> 16) & 0xFF);
    b0 = (byte)(((uint)number >> 24) & 0xFF);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接