c# int到字节[]

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

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

来源:RFC1014 3.2

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

364841 次浏览

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

现在,你很可能在一台小端机器上工作,而BitConverter.GetBytes()将给你反向的byte[]。所以你可以试试:

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;

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

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

int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
当我看到这个描述时,我有一种感觉,这个xdr整数只是一个大端“标准”整数,但它以最模糊的方式表示。二补符号更好地称为U2,它是我们在今天的处理器上使用的。字节顺序表明它是大端法表示法 所以,回答你的问题,你应该在你的数组(0 <——> 3,1 <——>2)逆元素,因为它们是用小端序编码的。只是为了确保,你应该首先检查BitConverter.IsLittleEndian,看看你在哪台机器上运行

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

Wikipedia上的二进制补码签名数字表示法

这里有另一种方法:我们都知道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]);
byte[] Take_Byte_Arr_From_Int(Int64 Source_Num)
{
Int64 Int64_Num = Source_Num;
byte Byte_Num;
byte[] Byte_Arr = new byte[8];
for (int i = 0; i < 8; i++)
{
if (Source_Num > 255)
{
Int64_Num = Source_Num / 256;
Byte_Num = (byte)(Source_Num - Int64_Num * 256);
}
else
{
Byte_Num = (byte)Int64_Num;
Int64_Num = 0;
}
Byte_Arr[i] = Byte_Num;
Source_Num = Int64_Num;
}
return (Byte_Arr);
}

为什么上面示例中的所有这些代码…

具有显式布局的结构以两种方式工作,并且没有性能影响。

更新:因为有一个关于如何处理字节序的问题,我添加了一个接口,说明如何抽象它。另一个实现结构可以处理相反的情况

public interface IIntToByte
{
Int32 Int { get; set;}


byte B0 { get; }
byte B1 { get; }
byte B2 { get; }
byte B3 { get; }
}


[StructLayout(LayoutKind.Explicit)]
public struct IntToByteLE : UserQuery.IIntToByte
{
[FieldOffset(0)]
public Int32 IntVal;


[FieldOffset(0)]
public byte b0;
[FieldOffset(1)]
public byte b1;
[FieldOffset(2)]
public byte b2;
[FieldOffset(3)]
public byte b3;


public Int32 Int {
get{ return IntVal; }
set{ IntVal = value;}
}


public byte B0 => b0;
public byte B1 => b1;
public byte B2 => b2;
public byte B3 => b3;
}
using static System.Console;


namespace IntToBits
{
class Program
{
static void Main()
{
while (true)
{
string s = Console.ReadLine();
Clear();
uint i;
bool b = UInt32.TryParse(s, out i);
if (b) IntPrinter(i);
}
}


static void IntPrinter(uint i)
{
int[] iarr = new int [32];
Write("[");
for (int j = 0; j < 32; j++)
{
uint tmp = i & (uint)Math.Pow(2, j);


iarr[j] = (int)(tmp >> j);
}
for (int j = 32; j > 0; j--)
{
if(j%8==0 && j != 32)Write("|");
if(j%4==0 && j%8 !=0) Write("'");
Write(iarr[j-1]);
}
WriteLine("]");
}
}
}```

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

byte[] intBytes = BitConverter.GetBytes(123);

. int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes)