193

我需要将其转换intbyte[]一种方法是使用BitConverter.GetBytes(). 但我不确定这是否符合以下规范:

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

来源:RFC1014 3.2

我怎样才能进行满足上述规范的 int 到 byte 转换?

4

9 回答 9

243

RFC 只是想说一个有符号整数是一个普通的 4 字节整数,字节以大端方式排序。

现在,您很可能正在使用 little-endian 机器,并且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;
于 2009-08-23T16:33:00.580 回答
45

这是另一种方法:众所周知,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]);
于 2009-08-23T16:40:39.503 回答
27

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

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

int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
于 2009-08-23T16:33:08.567 回答
10

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

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

于 2020-04-09T15:30:34.340 回答
4

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

具有显式布局的结构可以双向发挥作用,并且不会影响性能。

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

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; 
}
于 2018-03-03T18:17:13.497 回答
3

当我看到这个描述时,我有一种感觉,这个 xdr 整数只是一个大端“标准”整数,但它以最模糊的方式表示。二进制补码符号更好地称为 U2,它是我们在当今处理器上使用的符号。字节顺序表明它是一个大端符号。
因此,回答您的问题时,您应该反转数组中的元素 (0 <--> 3, 1 <-->2),因为它们是以小端序编码的。只是为了确保,您应该首先检查BitConverter.IsLittleEndian您正在运行的机器。

于 2009-08-23T16:35:08.377 回答
2

如果您想了解有关表示数字的各种方法(包括补码)的更多一般信息,请查看:

维基百科上的二进制补码和有符号数表示

于 2009-08-23T16:39:10.787 回答
0
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("]");
        }
    }
}```
于 2019-11-21T10:08:32.247 回答
-2
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);
}
于 2018-02-21T22:31:18.280 回答