views:

1590

answers:

6
+10  Q: 

C# int to byte[]

If I need to convert an int to byte[] I could use Bitconvert.GetBytes().

But if I should follow this:

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:

Taken from RFC1014 3.2.

What method should I use then if there is no method to do this? How would it look like if you write your own?

I don't understand the text 100% so I can't implement it on my own.

+15  A: 

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;
paracycle
`Enumerable.Reverse` extension method would return an `IEnumerable<T>` not an array. Last lines of snippets won't compile. You might want to try using `Array.Reverse` method.
Mehrdad Afshari
Yes, you are right. I typed off the top of my head and missed that one. Will edit the post to fix it.
paracycle
+5  A: 

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));
dtb
+1  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 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.

Ravadre
+1  A: 

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

Eric J.
+1  A: 

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]);
Maciek
dtb
Yeah, but I just wanted to show how this works
Maciek
It's big-endian, so MSB is stored first, so you should inverse your indices.
Ravadre
A: 

Take a look at

http://www.deveck.net/deveck.php/2009/09/06/really-machine-independent-binary-files-with-c%5Fsharp

this does the job for you