我需要将一个int转换为字节[],其中一种方法是使用BitConverter.GetBytes()。但我不确定这是否符合以下规格:

XDR有符号整数是一个32位的数据,它将整数编码为 范围[-2147483648,2147483647]。整数表示为 二的补符号。最高和最低有效字节为 分别是0和3。整数的声明如下:

来源:RFC1014 3.2

我怎么能做一个int到字节的转换,将满足上述规范?


当前回答

RFC只是试图说明一个有符号整数是一个正常的4字节整数,字节以大端序排列。

现在,您很可能正在一台小端序机器上工作,而BitConverter.GetBytes()将为您提供反向的字节[]。所以你可以试试:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;

然而,为了使代码最可移植,你可以这样做:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
    Array.Reverse(intBytes);
byte[] result = intBytes;

其他回答

RFC只是试图说明一个有符号整数是一个正常的4字节整数,字节以大端序排列。

现在,您很可能正在一台小端序机器上工作,而BitConverter.GetBytes()将为您提供反向的字节[]。所以你可以试试:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;

然而,为了使代码最可移植,你可以这样做:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
    Array.Reverse(intBytes);
byte[] result = intBytes;

这里有另一种方法:我们都知道1x字节= 8x位,而且,一个“常规”整数(int32)包含32位(4个字节)。我们可以使用>>操作符向右移位位(>>操作符不改变值)。

int intValue = 566;

byte[] bytes = new byte[4];

bytes[0] = (byte)(intValue >> 24);
bytes[1] = (byte)(intValue >> 16);
bytes[2] = (byte)(intValue >> 8);
bytes[3] = (byte)intValue;

Console.WriteLine("{0} breaks down to : {1} {2} {3} {4}",
    intValue, bytes[0], bytes[1], bytes[2], bytes[3]);

另一种方法是像这样使用BinaryPrimitives

byte[] intBytes = BitConverter.GetBytes(123); int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);

如果你想了解更多关于表示数字的各种方法(包括Two's Complement)的一般信息,请查看:

维基百科上2的补数和有符号数表示

getbytes (int)几乎做了你想要的,除了字节顺序是错误的。

可以使用IPAddress。在使用BitConverter之前交换整数值内的字节的hosttonnetwork方法。GetBytes或使用Jon Skeet的EndianBitConverter类。两种方法在可移植性方面都做了正确的事情(tm)。

int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));