Converting Little Endian to Big Endian

Convert Little Endian to Big Endian

OP's sample code is incorrect.

Endian conversion works at the bit and 8-bit byte level. Most endian issues deal with the byte level. OP's code is doing a endian change at the 4-bit nibble level. Recommend instead:

// Swap endian (big to little) or (little to big)
uint32_t num = 9;
uint32_t b0,b1,b2,b3;
uint32_t res;

b0 = (num & 0x000000ff) << 24u;
b1 = (num & 0x0000ff00) << 8u;
b2 = (num & 0x00ff0000) >> 8u;
b3 = (num & 0xff000000) >> 24u;

res = b0 | b1 | b2 | b3;

printf("%" PRIX32 "\n", res);

If performance is truly important, the particular processor would need to be known. Otherwise, leave it to the compiler.

[Edit] OP added a comment that changes things.

"32bit numerical value represented by the hexadecimal representation (st uv wx yz) shall be recorded in a four-byte field as (st uv wx yz)."

It appears in this case, the endian of the 32-bit number is unknown and the result needs to be store in memory in little endian order.

uint32_t num = 9;
uint8_t b[4];
b[0] = (uint8_t) (num >> 0u);
b[1] = (uint8_t) (num >> 8u);
b[2] = (uint8_t) (num >> 16u);
b[3] = (uint8_t) (num >> 24u);

[2016 Edit] Simplification

... The type of the result is that of the promoted left operand.... Bitwise shift operators C11 §6.5.7 3

Using a u after the shift constants (right operands) results in the same as without it.

b3 = (num & 0xff000000) >> 24u;
b[3] = (uint8_t) (num >> 24u);
// same as
b3 = (num & 0xff000000) >> 24;
b[3] = (uint8_t) (num >> 24);

Convert Little Endian to Big Endian - Not getting expected result

If you do 0x8000 << 8 you'll get 0x800000. If you | that with 0x80 you get the answer you now get. You need to filter away the upper part:

int swap = (num>>8) | (0xFF00 & (num<<8));

Suggestion: Use fixed width types, like uint8_t, uint16_t, uint32_t and uint64_t.

Converting a structure from Little endian to Big endian

Converting a whole struct from/to little or big endian does not make sense, because endianness is a property of a multi-byte scalar type representation, e.g. a single UInt16 or UInt32. When converting a struct to its "on-the-wire representation" you go through it one element at a time, and prepare its representation element-by-element.

Bit fields represent a special case, because their ordering is implementation-defined. You need to serialize them into a single byte in the order that you prefer. Use hton/ntoh functions to do the conversion of the individual multi-byte elements, i.e. Length and TEID.

How do I convert between big-endian and little-endian values in C++?

If you're using Visual C++ do the following: You include intrin.h and call the following functions:

For 16 bit numbers:

unsigned short _byteswap_ushort(unsigned short value);

For 32 bit numbers:

unsigned long _byteswap_ulong(unsigned long value);

For 64 bit numbers:

unsigned __int64 _byteswap_uint64(unsigned __int64 value);

8 bit numbers (chars) don't need to be converted.

Also these are only defined for unsigned values they work for signed integers as well.

For floats and doubles it's more difficult as with plain integers as these may or not may be in the host machines byte-order. You can get little-endian floats on big-endian machines and vice versa.

Other compilers have similar intrinsics as well.

In GCC for example you can directly call some builtins as documented here:

uint32_t __builtin_bswap32 (uint32_t x)
uint64_t __builtin_bswap64 (uint64_t x)

(no need to include something). Afaik bits.h declares the same function in a non gcc-centric way as well.

16 bit swap it's just a bit-rotate.

Calling the intrinsics instead of rolling your own gives you the best performance and code density btw..

Converting Little Endian to Big Endian

The thing you need to realize is that endian swaps deal with the bytes that represent the integer. So the 4 byte number 27 looks like 0x0000001B. To convert that number, it needs to go to 0x1B000000... With your example, the hex representation of 123456789 is 0x075BCD15 which needs to go to 0x15CD5B07 or in decimal form 365779719.

The function Stacker posted is moving those bytes around by bit shifting them; more specifically, the statement i&0xff takes the lowest byte from i, the << 24 then moves it up 24 bits, so from positions 1-8 to 25-32. So on through each part of the expression.

For example code, take a look at this utility.

Python) Convert Big Endian to Little Endian

Using a bytearray (Try it online!):

data = "F324658951425AF3EB0011"
bits = [16, 8, 8, 32, 8, 16]

b = bytearray.fromhex(data)
i = 0
for n in bits:
n //= 8
b[i:i+n] = reversed(b[i:i+n])
i += n
print(b.hex().upper())

Or with memoryview (Try it online!):

data = "F324658951425AF3EB0011"
bits = [16, 8, 8, 32, 8, 16]

b = bytearray.fromhex(data)
m = memoryview(b)
for n in bits:
n //= 8
m[:n] = m[n-1::-1]
m = m[n:]
print(b.hex().upper())

converting big endian to Little endian

You apply ntohs() or htons() to a single byte value (uint8_t) but these
functions (or macros) consider two-byte values.

Anyway, applying these functions one after each other will not change the value; think about it in the daily life, you swap two objects, and swap them again.

If you want to consider every pair of bytes in array as a 16-bit integer
in big-endian order and stored them in host order, maybe should
you try this:

uint8_t array[10]={...};
uint16_t output[5];
for(int i=0; i<5; ++i)
{
output[i]=(uint16_t)((array[2*i+1]<<8)|array[2*i+0]));
}

How to convert little endian to big endian in java .wav files

Found a way ... it's pretty easy:

private void getWavFile(File outFile, byte[] decodedData) throws IOException {
AudioFormat format = new AudioFormat(48000.0F, 16, 2, true, true);
boolean convertable = AudioSystem.isConversionSupported(
new AudioFormat(48000, 16, 2, true, false), format);
System.out.println("Can be converted: " + convertable);
AudioSystem.write(new AudioInputStream(
new ByteArrayInputStream(decodedData), format, decodedData.length),
AudioFileFormat.Type.WAVE, outFile);
File converted = new File("converted.wav");
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(
new AudioFormat(48000, 16, 2, true, false),
AudioSystem.getAudioInputStream(outFile));
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, converted);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
}
}


Related Topics



Leave a reply



Submit