C# int 到 byte[]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1318933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# int to byte[]
提问by Peter
I need to convert an int
to a byte[]
one way of doing it is to use BitConverter.GetBytes()
. But im unsure if that matches the following specification:
我需要将 an 转换int
为byte[]
一种方法是使用BitConverter.GetBytes()
. 但我不确定这是否符合以下规范:
An XDR signed integer is a 32-bit datum that encodes an integer in the range [-2147483648,2147483647]. The integer is represented in two's complement notation. The most and least significant bytes are 0 and 3, respectively. Integers are declared as follows:
XDR 有符号整数是一个 32 位数据,它对 [-2147483648,2147483647] 范围内的整数进行编码。整数以二进制补码表示法表示。最高和最低有效字节分别为 0 和 3。整数声明如下:
Source: RFC1014 3.2
来源: RFC1014 3.2
How could i do a int to byte transformation that would satisfy the above specification?
我怎么能做一个满足上述规范的 int 到 byte 转换?
采纳答案by paracycle
The RFC is just trying to say that a signed integer is a normal 4-byte integer with bytes ordered in a big-endian way.
RFC 只是想说一个有符号整数是一个普通的 4 字节整数,字节以大端方式排序。
Now, you are most probably working on a little-endian machine and BitConverter.GetBytes()
will give you the byte[]
reversed. So you could try:
现在,你是最有可能工作一小端机器上,并且BitConverter.GetBytes()
会给你的byte[]
逆转。所以你可以试试:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;
For the code to be most portable, however, you can do it like this:
但是,为了使代码最具有可移植性,您可以这样做:
int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
byte[] result = intBytes;
回答by dtb
BitConverter.GetBytes(int)
almost does what you want, except the endianness is wrong.
BitConverter.GetBytes(int)
几乎可以做你想做的事,除了字节序是错误的。
You can use the IPAddress.HostToNetworkmethod to swap the bytes within the the integer value before using BitConverter.GetBytes
or use Jon Skeet's EndianBitConverter class. Both methods do the right thing(tm) regarding portability.
在使用或使用 Jon Skeet 的EndianBitConverter 类之前,您可以使用IPAddress.HostToNetwork方法交换整数值中的字节。这两种方法都在便携性方面做正确的事情(tm)。BitConverter.GetBytes
int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
回答by Marcin Deptu?a
When I look at this description, I have a feeling, that this xdr integer is just a big-endian "standard" integer, but it's expressed in the most obfuscated way. Two's complement notationis better know as U2, and it's what we are using on today's processors. The byte order indicates that it's a big-endiannotation.
So, answering your question, you should inverse elements in your array (0 <--> 3, 1 <-->2), as they are encoded in little-endian. Just to make sure, you should first check BitConverter.IsLittleEndian
to see on what machine you are running.
当我看到这个描述时,我有一种感觉,这个 xdr 整数只是一个大端“标准”整数,但它以最模糊的方式表达。二进制补码表示法更好地称为 U2,它是我们在今天的处理器上使用的。字节顺序表明它是大端表示法。
因此,回答您的问题,您应该反转数组中的元素 (0 <--> 3, 1 <-->2),因为它们以小端编码。只是为了确保,您应该首先检查BitConverter.IsLittleEndian
您正在运行的机器。
回答by Eric J.
If you want more general information about various methods of representing numbers including Two's Complement have a look at:
如果您想了解有关表示数字的各种方法(包括二进制补码)的更多一般信息,请查看:
Two's Complementand Signed Number Representationon Wikipedia
回答by Maciek
Here's another way to do it: as we all know 1x byte = 8x bits and also, a "regular" integer (int32) contains 32 bits (4 bytes). We can use the >> operator to shift bits right (>> operator does not change value.)
这是另一种方法:众所周知,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]);
回答by Valery Rode
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);
}
回答by Sten Petrov
Why all this code in the samples above...
为什么上面示例中的所有这些代码...
A struct with explicit layout acts both ways and has no performance hit.
具有显式布局的结构可以双向运行并且不会影响性能。
Update: Since there's a question on how to deal with endianness I added an interface that illustrates how to abstract that. Another implementing struct can deal with the opposite case
更新:因为有一个关于如何处理字节序的问题,所以我添加了一个接口来说明如何抽象它。另一个实现结构可以处理相反的情况
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;
}
回答by Александр Гром
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("]");
}
}
}```
回答by Denis
The other way is to use BinaryPrimitiveslike so
另一种方法是像这样使用BinaryPrimitives
byte[] intBytes = BitConverter.GetBytes(123);
int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);
byte[] intBytes = BitConverter.GetBytes(123);
int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);