Pet*_*ter 158 .net c# nfs bit-manipulation
我需要转换int为byte[]一种方法来做它是使用BitConverter.GetBytes().但我不确定这是否符合以下规范:
XDR带符号整数是一个32位数据,它编码[-2147483648,2147483647]范围内的整数.整数用二进制补码表示.最高和最低有效字节分别为0和3.整数声明如下:
资源: RFC1014 3.2
我怎样才能进行满足上述规范的int到byte转换?
par*_*cle 207
RFC只是试图说有符号整数是一个普通的4字节整数,其字节以big-endian方式排序.
现在,你很可能正在使用一个小端机器,BitConverter.GetBytes()并会给你byte[]相反的结果.所以你可以尝试:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;
Run Code Online (Sandbox Code Playgroud)
但是,为了使代码最便携,您可以这样做:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
byte[] result = intBytes;
Run Code Online (Sandbox Code Playgroud)
Mac*_*iek 35
这是另一种方法:我们都知道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]);
Run Code Online (Sandbox Code Playgroud)
dtb*_*dtb 23
BitConverter.GetBytes(int) 几乎做你想要的,除了字节顺序是错误的.
在使用或使用Jon Skeet的EndianBitConverter类之前,您可以使用IPAddress.HostToNetwork方法交换整数值中的字节.两种方法都做了关于可移植性的正确的事情(tm).BitConverter.GetBytes
int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
Run Code Online (Sandbox Code Playgroud)
为什么上面示例中的所有代码......
具有显式布局的结构体具有双向作用,并且不会影响性能。
更新:由于存在如何处理字节顺序的问题,我添加了一个接口来说明如何抽象它。另一个实现结构可以处理相反的情况
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;
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是像这样使用BinaryPrimitives
byte[] intBytes = BitConverter.GetBytes(123);
int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);
在 .NET Core 2.1+ 和 .NET 5+ 中,您可以BinaryPrimitives.WriteInt32BigEndian()像这样使用:
int intVal = ...;
byte[] bytes = new byte[4];
BinaryPrimitives.WriteInt32BigEndian(bytes, intVal);
Run Code Online (Sandbox Code Playgroud)