Simplest way to copy int to byte[]
Asked Answered
D

8

12

I have a byte[] and i am iterating through a list of ints(and other data) and i want to copy the int to my byteArray[index*4] How do i do this?

Deirdre answered 17/8, 2009 at 10:6 Comment(0)
F
22

BitConverter is quite possibly your friend.

However, that generally returns you a new byte array. It also doesn't let you specify endianness. I have the EndianBitConverter class in MiscUtil which has methods to convert primitive types by copying the data directly into an existing byte array.

For instance:

// Copy the bytes from the integer "value" into a byte array
// (buffer) starting at index 5
EndianBitConverter.Little.CopyBytes(value, buffer, 5);
Furie answered 17/8, 2009 at 10:8 Comment(2)
wow, you learn something new every day :) Didn't even know that existed!Stancil
Agreed, better than the shifting approach, because you don't need to think about endian-ness. (Unless, of course, he needs to change it).Simonasimonds
S
10

Do it how the BinaryWriter does it:

buffer[0] = (byte) value;
buffer[1] = (byte) (value >> 8);
buffer[2] = (byte) (value >> 0x10);
buffer[3] = (byte) (value >> 0x18);

(obviously this will copy the int into the first 4 bytes of the array)

Stancil answered 17/8, 2009 at 10:9 Comment(1)
Is this endianness independent?Abbess
G
7

I'll try to summarize some of the previous answers to make something new

Step 1. As Jon Skeet said before:

BitConverter is quite possibly your friend.

However, that generally returns you a new byte array.

Step 2. You can find the source code of BitConverter.GetBytes(int value) method:

public static unsafe byte[] GetBytes(int value)
{
    byte[] numArray = new byte[4];
    fixed (byte* numPtr = numArray)
        *(int*) numPtr = value;
    return numArray;
}

Step 3. Using imagination and changing a few lines in the code from step 2 so it could save the data to an existing array:

public static unsafe byte[] GetBytes(int value, int buffer[], int offset)
{
    // Here should be a range check. For example:
    // if (offset > buffer.Length + sizeof(int)) throw new IndexOutOfRangeException();

    fixed (byte* numPtr = &buffer[offset])
        *(int*) numPtr = value;
}
Gazpacho answered 24/11, 2012 at 20:50 Comment(3)
Step 2 & 3 looks like its Endian dependent. Can you please confirm?Lachrymatory
Yes, both steps are Endian dependent.Gazpacho
If we use bit shift operators then it can be endian independent code?Lachrymatory
R
6

There are many different ways to do it, but to make it nicer, lets use a new feature of c#: extensions.

An integer of the 32 bit variety takes 4 bytes, so it will occupy 4 spots in the byte[]. How do you break an integer in its 4 constituent bytes? You can do it using the bit manipulation operator >>. That operator shifts the bits in the integer by the specified number of bits. For example:

integer = 10399
binary = 00101000 10011111
10399 >> 1 == 0010100 01001111 each bit shifted by 1

Since a byte is 8 bits if we shift the integer by 8 bits we will have the new second byte value of the integer in the right-most bits position

10399 >> 8 = 00000000 00101000

Notice how the second byte is not the first byte and the rest of the bits have been replaced by 0.

We can use this trick to move the bytes into the first position, then force a cast to byte, which will discard the 3 other bytes and will leave us the last bytes value:

(byte)(10399 >> 8) == 0010100

So, using this technique for the 4 bytes will give us access to each one and we will copy them in a destination array that was passed to our new CopyToByteArray method:

public static class Int32Extension
{
    public static void CopyToByteArray(this int source, byte[] destination, int offset)
    {
        if (destination == null)
            throw new ArgumentException("Destination array cannot be null");

        // check if there is enough space for all the 4 bytes we will copy
        if (destination.Length < offset + 4)
            throw new ArgumentException("Not enough room in the destination array");

        destination[offset] = (byte)(source >> 24); // fourth byte
        destination[offset+1] = (byte)(source >> 16); // third byte
        destination[offset+2] = (byte)(source >> 8 ); // second byte
        destination[offset+3] = (byte)source; // last byte is already in proper position
    }
}

Note that we could have copied the bytes in reverse order, that is up to your implementation.

The extension function will allow you to access the new function as a member of the integer class:

int something = 20;
byte[] array = new byte[4];
something.CopyToByteArray(array,0);
Rase answered 17/8, 2009 at 10:30 Comment(0)
S
2

Update 2022

A few years have passed since the question was asked. If someone is looking for it today, there is a simpler version with NET 6.

The BinaryPrimitives class

Write int or other primitives to array

BinaryPrimitives.WriteInt32LittleEndian(array, myInt);

And of course many more methods to write different primitives as Big- or Little-Endian

Sorrows answered 10/8, 2022 at 19:0 Comment(0)
P
1
byte[] bytes = new byte[listOfInts.Count * sizeof(int)];
int pos = 0;
foreach(int i in listOfInts)
{
    byte[] b = BitConverter.GetBytes(i);
    b.CopyTo(bytes, pos);
    pos += b.Length;
}
Presumably answered 17/8, 2009 at 10:13 Comment(0)
S
1

Buffer.BlockCopy(intArray, 0, byteArray, 0, 4*intArray.Length)

Copies data between two arrays. The last argument is the amount of data to copy in bytes.

Sandbox answered 17/8, 2009 at 10:20 Comment(0)
G
0

Generalizing ADB's exquisit answer:

public static class Int32Extension
{

    /// <summary>
    /// Copies an int to a byte array: Byte order and sift order are inverted.
    /// </summary>
    /// <param name="source">The integer to convert.</param>
    /// <param name="destination">An arbitrary array of bytes.</param>
    /// <param name="offset">Offset into the desination array.</param>
    public static void CopyToByteArray(this int source, byte[] destination, int offset)
    {
        if (destination == null)
            throw new ArgumentException("Destination array cannot be null");

        // check if there is enough space for all the 4 bytes we will copy
        if (destination.Length < offset + sizeof(int))
            throw new ArgumentException("Not enough room in the destination array");

        for (int i = 0, j = sizeof(int) - 1; i < sizeof(int); i++, --j) {
            destination[offset + i] = (byte) (source >> (8 * j));
        }
    }

    /// <summary>
    /// Copies an int to a to byte array Little Endian: Byte order and sift order are the same.
    /// </summary>
    /// <param name="source">The integer to convert.</param>
    /// <param name="destination">An arbitrary array of bytes.</param>
    /// <param name="offset">Offset into the desination array.</param>
    public static void CopyToByteArrayLE(this int source, byte[] destination, int offset)
    {
        if (destination == null)
            throw new ArgumentException("Destination array cannot be null");

        // check if there is enough space for all the 4 bytes we will copy
        if (destination.Length < offset + sizeof(int))
            throw new ArgumentException("Not enough room in the destination array");

        for (int i = 0, j = 0; i < sizeof(int); i++, j++) {
            destination[offset + i] = (byte) (source >> (8 * j));
        }
    }
}
Greedy answered 16/11, 2014 at 21:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.