C# int to byte[]

C#.NetBit ManipulationNfs

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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 - C#

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 - C#

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 - C#

The other way is to use BinaryPrimitives like so

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

Solution 5 - C#

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

Solution 6 - C#

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 notation is better know as U2, and it's what we are using on today's processors. The byte order indicates that it's a big-endian notation.
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.

Solution 7 - C#

If you want more general information about various methods of representing numbers including Two's Complement have a look at:

Two's Complement and Signed Number Representation on Wikipedia

Solution 8 - C#

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

Solution 9 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeterView Question on Stackoverflow
Solution 1 - C#paracycleView Answer on Stackoverflow
Solution 2 - C#MaciekView Answer on Stackoverflow
Solution 3 - C#dtbView Answer on Stackoverflow
Solution 4 - C#DenisView Answer on Stackoverflow
Solution 5 - C#Sten PetrovView Answer on Stackoverflow
Solution 6 - C#Marcin DeptułaView Answer on Stackoverflow
Solution 7 - C#Eric J.View Answer on Stackoverflow
Solution 8 - C#Александр ГромView Answer on Stackoverflow
Solution 9 - C#Valery RodeView Answer on Stackoverflow