Insert array of hex codes into an integer
Asked Answered
E

2

5

I'm trying to do something that I thought would be pretty basic but either I'm just ignoring something obvious or it is actually a bit tricky. My problem is: I have an array of 4 chars that contains 4 hex values. For example:

array[0] = 0xD8
array[1] = 0xEC
array[2] = 0xA2 
array[3] = 0x83

I want to store this array in an integer with the combined value, in this case 0xD8ECA283

I've tried doing logical OR and then shifting the bits and with this method I managed to store the value of 0xD8 in the integer, but not the rest. Any tips would be appreciated.

Eras answered 30/4, 2015 at 13:28 Comment(7)
Show the code and we'll help you from there.Desmarais
Why not just work with the array as if it were a pointer to an integer? E.g. int integer = *((int*)array).Shimmer
@Shimmer Because of Endianness.Charlottetown
@Shimmer That may not work due to endianness issues. The value you get will be different depending on whether it's a big-endian or little-endian plaformDesmarais
@Witiko: Also you might face alignment issues.Restrainer
@Shimmer on top of endianness and alignment issues, it violates strict aliasingColumbite
@ali: What kind of alignment issues?Shimmer
D
5

This should do it:

int i;
int combined = 0;
for (i = 0; i < 4; i++) {
    combined = (combined << 8) | ((unsigned char) array[i]);
}
Distasteful answered 30/4, 2015 at 13:32 Comment(1)
Wow, this is actually pretty close to what I was trying so at least I was at the right track. Should have kept at it longer. Anyway, thanks for the helpEras
E
6

Use the binary OR operator, and an integer whose precision is guaranteed to be at least 32 bits, which is the type unsigned long (although the type uint_least32_t could also be used).

Unsigned integer is used so any potential undefined and/or implementation defined behavior that is present when shifting signed integers is avoided.

This solution is independent of endianness.

unsigned long a = ( ( ( unsigned long )array[0] & 0xFF ) << 24 ) |
                  ( ( ( unsigned long )array[1] & 0xFF ) << 16 ) |
                  ( ( ( unsigned long )array[2] & 0xFF ) << 8 ) |
                  ( ( ( unsigned long )array[3] & 0xFF ) << 0 ) ;

Casts to ( unsigned long ) are made to avoid intermediate implicit conversion to int.
The & 0xFF operation is there to remove unnecessary bits (if there were any in an unlikely scenario where CHAR_BIT != 8).

Evelinaeveline answered 30/4, 2015 at 13:32 Comment(2)
@DrKoch Yes, it was intentional for consistency and readability.Evelinaeveline
This solved my problem, but I accepted another answer because I thought it was a bit easier to read. But thanks anywayEras
D
5

This should do it:

int i;
int combined = 0;
for (i = 0; i < 4; i++) {
    combined = (combined << 8) | ((unsigned char) array[i]);
}
Distasteful answered 30/4, 2015 at 13:32 Comment(1)
Wow, this is actually pretty close to what I was trying so at least I was at the right track. Should have kept at it longer. Anyway, thanks for the helpEras

© 2022 - 2024 — McMap. All rights reserved.