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

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

来源:RFC1014 3.2

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


当前回答

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

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

其他回答

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

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

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("]");
        }
    }
}```

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

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

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

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; 
}

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

byte[] intBytes = BitConverter.GetBytes(123); int actual = BinaryPrimitives.ReadInt32LittleEndian(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;