C++ int to byte array

140,380

Solution 1

Using std::vector<unsigned char>:

#include <vector>
using namespace std;

vector<unsigned char> intToBytes(int paramInt)
{
     vector<unsigned char> arrayOfByte(4);
     for (int i = 0; i < 4; i++)
         arrayOfByte[3 - i] = (paramInt >> (i * 8));
     return arrayOfByte;
}

Solution 2

You don't need a whole function for this; a simple cast will suffice:

int x;
static_cast<char*>(static_cast<void*>(&x));

Any object in C++ can be reinterpreted as an array of bytes. If you want to actually make a copy of the bytes into a separate array, you can use std::copy:

int x;
char bytes[sizeof x];
std::copy(static_cast<const char*>(static_cast<const void*>(&x)),
          static_cast<const char*>(static_cast<const void*>(&x)) + sizeof x,
          bytes);

Neither of these methods takes byte ordering into account, but since you can reinterpret the int as an array of bytes, it is trivial to perform any necessary modifications yourself.

Solution 3

You can get individual bytes with anding and shifting operations:

byte1 =  nint & 0x000000ff
byte2 = (nint & 0x0000ff00) >> 8
byte3 = (nint & 0x00ff0000) >> 16
byte4 = (nint & 0xff000000) >> 24

Solution 4

Another useful way of doing it that I use is unions:

union byteint
{
    byte b[sizeof int];
    int i;
};
byteint bi;
bi.i = 1337;
for(int i = 0; i<4;i++)
    destination[i] = bi.b[i];

This will make it so that the byte array and the integer will "overlap"( share the same memory ). this can be done with all kinds of types, as long as the byte array is the same size as the type( else one of the fields will not be influenced by the other ). And having them as one object is also just convenient when you have to switch between integer manipulation and byte manipulation/copying.

Solution 5

An int (or any other data type for that matter) is already stored as bytes in memory. So why not just copy the memory directly?

memcpy(arrayOfByte, &x, sizeof x);

A simple elegant one liner that will also work with any other data type.



If you need the bytes reversed you can use std::reverse

memcpy(arrayOfByte, &x, sizeof x);
std::reverse(arrayOfByte, arrayOfByte + sizeof x);

or better yet, just copy the bytes in reverse to begin with

BYTE* p = (BYTE*) &x;
std::reverse_copy(p, p + sizeof x, arrayOfByte);

If you don't want to make a copy of the data at all, and just have its byte representation

BYTE* bytes = (BYTE*) &x;
Share:
140,380
justme_
Author by

justme_

Updated on August 23, 2020

Comments

  • justme_
    justme_ over 3 years

    I have this method in my java code which returns byte array for given int:

    private static byte[] intToBytes(int paramInt)
    {
         byte[] arrayOfByte = new byte[4];
         ByteBuffer localByteBuffer = ByteBuffer.allocate(4);
         localByteBuffer.putInt(paramInt);
         for (int i = 0; i < 4; i++)
             arrayOfByte[(3 - i)] = localByteBuffer.array()[i];
         return arrayOfByte;
    }
    

    Can someone give me tip how can i convert that method to C++?

  • James Kanze
    James Kanze about 13 years
    Maybe. Not on an Intel box (or at least it won't give the same results).
  • Sxl
    Sxl about 13 years
    I'm curious: why did you do two static_cast<>s instead of one reinterpret_cast<>?
  • BlackBear
    BlackBear about 13 years
    he asked exactly the opposite :)
  • jberg
    jberg about 13 years
    wow, I fail! Always feel like if I don't reply right away a million other people will. I was right, but I suppose I should make sure to get the question right hahaha
  • James McNellis
    James McNellis about 13 years
    To elaborate: There was lengthy discussion here a year or two ago about whether a reinterpret_cast was guaranteed to be equivalent to the pair of static_cast. If I recall correctly it was basically agreed that both should always work, but it was all very convoluted so I still avoid reinterpret_cast.
  • BlackBear
    BlackBear about 13 years
    yeah, me too try to answer as fast as possible, and sometimes write such a bullsh*ts ;)
  • James Kanze
    James Kanze about 13 years
    The Java code generates a big endian representation; you generate a littel endian one. (I'd also just use the shift count as the loop control: int i = 32; while ( i != 0 ) { arrayOfByte[i] = paramInt >> i; i -= 8; }
  • Tomáš Zato
    Tomáš Zato about 11 years
    @JamesKanze: wait... can you really use i to access arrayOfByte when it will have values of [32, 24, 16, 8]? I think you should do arrayOfByte[i/8].
  • James Kanze
    James Kanze about 11 years
    @TomášZato Yes; The index should be i/8.
  • Jason Rice
    Jason Rice about 8 years
    It's still useful.
  • MateuszL
    MateuszL over 5 years
    Reading from wrong union member is Undefined Behavior and misuse of union
  • Lightness Races in Orbit
    Lightness Races in Orbit over 5 years
    This is wrong. This is not what unions are for. This is not how unions work. Myth!
  • Yan
    Yan almost 5 years
    The result of this method seems to depend on the endianness. Assume x=0x4142, run this process on a little endian machine, iterate the bytes array and print each byte, you'll get "BA". If you want to get "AB", you have to reverse the result by yourself.
  • RoboticForest
    RoboticForest over 4 years
    On some machines this is very clever, but sadly it's not standard and is dangerous. See this union reference. "The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined, and it's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union."
  • Ayxan Haqverdili
    Ayxan Haqverdili almost 4 years
    Is it well defined to cast an int to a byte array? I thought accessing an object as if it were some other type is undefined behavior.