C# int to byte[]

345,488

Solution 1

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.

Now, you are most probably working on a little-endian machine and BitConverter.GetBytes() will give you the byte[] reversed. So you could try:

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;

Solution 2

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.)

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]);

Solution 3

BitConverter.GetBytes(int) almost does what you want, except the endianness is wrong.

You can use the IPAddress.HostToNetwork method 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.

int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));

Solution 4

The other way is to use BinaryPrimitives like so

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

Solution 5

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; 
}
Share:
345,488

Related videos on Youtube

Raven
Author by

Raven

https://github.com/AnderssonPeter

Updated on April 10, 2020

Comments

  • Raven
    Raven about 4 years

    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 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:

    Source: RFC1014 3.2

    How could i do a int to byte transformation that would satisfy the above specification?

  • Feidex
    Feidex almost 15 years
    The array initializer and the xor (^) and & 0xFF bits are unnecessary.
  • Marcin Deptuła
    Marcin Deptuła almost 15 years
    It's big-endian, so MSB is stored first, so you should inverse your indices.
  • Nick
    Nick over 12 years
    Or use ToArray. byte[] result = BitConverter.GetBytes(intValue).Reverse().ToArray();
  • jocull
    jocull about 11 years
    Can we add an example of going the opposite way? (bytes back to integer)
  • Timeless
    Timeless over 6 years
    I use this because of performance. If I don't care about this small difference, I will go for the accepted answer.
  • Gregor Doroschenko
    Gregor Doroschenko over 6 years
    please add more explanation
  • Raven
    Raven over 6 years
    Thanks for the answer, why did you choose to write a new implementation instead of using the stackoverflow.com/a/1318948/58553 ? (are there any pro or cons with your solution)
  • Valery Rode
    Valery Rode over 6 years
    In case when project need to be developed with not only one language, it can be useful realize code similarity between languages in situation when identical ideas must be implemented. This way may help with mistakes catching. Sure using ‘c#’ function ‘BitConverter.GetBytes’ with ‘Endian’ checking that all what needed in most cases. And more, in some situation may happened use conversion not only to Int32(4 bytes) or Int64(8 bytes) but to other number of bytes. Thanks.
  • CodesInChaos
    CodesInChaos about 6 years
    You should wrap that code in an unchecked block. Currently it only works if integer overflow checking is disabled in the compiler settings.
  • Raven
    Raven about 6 years
    How would you use this? and secondly would you get the same result even is you run this on 'big-endian' and on 'little-endian'.
  • Sten Petrov
    Sten Petrov about 6 years
    @Peter here's an update. It should still perform better than shifts
  • Nyerguds
    Nyerguds about 6 years
    This isn't really universally usable at all... it always returns an 8-byte array, which brings a lot of extra work with input values that aren't 64-bit ints. I'd logically want a 2-byte array when converting an Int16.
  • Craig.Feied
    Craig.Feied about 6 years
    yup. Basically a c++ union implemented as c# structs. This is super-fast and is good for packing and unpacking all kinds of things that don't fit nicely into the bitconverter/endian problem solutions. IIRC, NAudio uses this approach to very good effect.
  • derHugo
    derHugo about 5 years
    why the last line byte[] result = intBytes; ? isn't intBytes already the array you want?
  • paracycle
    paracycle about 5 years
    @derHugo That's correct, result is redundant in this code piece. However, I felt that it was more pedagogical to explicitly show the reader what the result was than assuming that they can figure out that the result is contained in some variable named intBytes. Besides, doing the assignment is cheap since it does not copy the memory nor allocate new memory, it just adds a new name to the already allocated array. So why not do it?
  • John Evans
    John Evans over 4 years
    This is the best answer and it's kinda sad that this isn't the top but just tells you something about the state of programming in 2019
  • Vinigas
    Vinigas over 3 years
    This should be top answer, but consider adding: docs.microsoft.com/en-us/dotnet/api/…
  • rustyx
    rustyx about 3 years
    This should be the accepted answer. But beware - it's available starting from .NET 5.0 and .NET Core 2.1.