C ++ int в байтовый массив - PullRequest
       17

C ++ int в байтовый массив

23 голосов
/ 07 апреля 2011

У меня есть этот метод в моем Java-коде, который возвращает байтовый массив для данного типа 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;
}

Может кто-нибудь дать мне совет, как я могу преобразовать этот метод в C ++?

Ответы [ 9 ]

48 голосов
/ 07 апреля 2011

Вам не нужна целая функция для этого;будет достаточно простого приведения:

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

Любой объект в C ++ может быть интерпретирован как массив байтов.Если вы действительно хотите скопировать байты в отдельный массив, вы можете использовать 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);

Ни один из этих методов не учитывает порядок байтов, но, поскольку вы можете переосмыслить int как массив байтов, тривиально выполнить любые необходимые изменения самостоятельно.

19 голосов
/ 07 апреля 2011

Использование 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;
}
12 голосов
/ 14 февраля 2013

Другой полезный способ сделать это, который я использую, это союзы:

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

Это сделает так, что байтовый массив и целое число будут «перекрываться» (совместно использовать одну и ту же память). это может быть сделано со всеми типами типов, если размер байтового массива совпадает с размером типа (иначе одно поле не будет зависеть от другого). И иметь их как один объект также просто удобно, когда вам нужно переключаться между целочисленной манипуляцией и манипулированием / копированием байтов.

5 голосов
/ 20 апреля 2017

Int в байтах и ​​наоборот.

unsigned char bytes[4];
unsigned long n = 1024;

bytes[0] = (n >> 24) & 0xFF;
bytes[1] = (n >> 16) & 0xFF;
bytes[2] = (n >> 8) & 0xFF;
bytes[3] = n & 0xFF;

printf("%x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);


int num = 0;
for(int i = 0; i < 4; i++)
 {
 num <<= 8;
 num |= bytes[i];
 }


printf("number %d",num);
5 голосов
/ 07 апреля 2011

Вы можете получить отдельные байты с операциями перемещения и сдвига:

byte1 =  nint & 0x000000ff
byte2 = (nint & 0x0000ff00) >> 8
byte3 = (nint & 0x00ff0000) >> 16
byte4 = (nint & 0xff000000) >> 24
4 голосов
/ 07 апреля 2011
std::vector<unsigned char> intToBytes(int value)
{
    std::vector<unsigned char> result;
    result.push_back(value >> 24);
    result.push_back(value >> 16);
    result.push_back(value >>  8);
    result.push_back(value      );
    return result;
}
2 голосов
/ 11 апреля 2019

int (или любой другой тип данных в этом отношении) уже сохранен как байты в памяти.Так почему бы просто не скопировать память напрямую?

memcpy(arrayOfByte, &x, sizeof x);

Простой элегантный вкладыш, который также будет работать с любыми другими типами данных.



Если вам нужны байтыв обратном порядке вы можете использовать std :: reverse

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

или еще лучше, просто скопируйте байты в обратном порядке, чтобы начать с

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

Если вы не хотите делатькопия данных вообще и просто имеет свое байтовое представление

BYTE* bytes = (BYTE*) &x;
1 голос
/ 07 апреля 2011
return ((byte[0]<<24)|(byte[1]<<16)|(byte[2]<<8)|(byte[3]));

: D

0 голосов
/ 15 января 2019

Я знаю, что на этот вопрос уже есть ответы, но я дам свое решение этой проблемы. Я использую функцию шаблона и целочисленное ограничение на него.

Вот мое решение:

#include <type_traits>
#include <vector>

template <typename T,
          typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
std::vector<uint8_t> splitValueToBytes(T const& value)
{
    std::vector<uint8_t> bytes;

    for (size_t i = 0; i < sizeof(value); i++)
    {
        uint8_t byte = value >> (i * 8);
        bytes.insert(bytes.begin(), byte);
    }

    return bytes;
}
...