Reputation: 9
Does anyone know of a library that provides a function that performs this logic or perhaps a method to perform this logic?
I'm trying to convert:
unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";
to:
94882212005342 / 0x0000564b7c8ac5de
I'm aware I could loop over each individual byte in test
and utilize sprintf
to convert each byte to string and concatenate them into a buffer with strcat
and convert the buffer string to unsigned long long
via strtoull
. However I'm looking for something more comprehensive and simple. Is there such a way?
Upvotes: 0
Views: 2481
Reputation: 214920
Just for the record, you can just simply do this:
#include <stdio.h>
#include <inttypes.h>
int main(int argc, char *argv[])
{
unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";
uint64_t val=0;
for(size_t i=0; i<8; i++)
val |= (uint64_t)test[i] << (7-i)*8;
printf("%" PRIu64 " %" PRIX64, val, val);
}
Upvotes: 0
Reputation: 31429
A fun BUT NOT RECOMMENDED way of doing this. If you want a proper solution, look at KamilCuk's answer
#include <stdio.h>
#include <string.h>
// Reverse an 8-byte array
void rev(unsigned char *s) {
unsigned char *end = s + 7; // Evil hard coded value
while(s<end) {
unsigned char tmp = *s;
*s = *end;
*end = tmp;
s++;
end--;
}
}
int main(void) {
unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";
rev(test); // Reverse the array
long l;
memcpy(&l, test, sizeof test);
printf("%zx\n", l);
}
Note that the standard does not dictate the byte order. This is what works on MY machine. It will be the same on most machines, but if portability to other architectures is important to you. Don't even consider this.
However, since you're saying that the value is an address, I'd recommend using uintptr_t
instead of long
.
Upvotes: -1
Reputation: 141768
It's just maths.
unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";
unsigned long long num =
(unsigned long long)test[0] << 56 |
(unsigned long long)test[1] << 48 |
(unsigned long long)test[2] << 40 |
(unsigned long long)test[3] << 32 |
(unsigned long long)test[4] << 24 |
(unsigned long long)test[5] << 16 |
(unsigned long long)test[6] << 8 |
(unsigned long long)test[7] << 0;
Remember to cast to type wide enough before shifting.
You have 8 values:
{ 0x00, 0x00, 0x56, 0x4b, 0x7c, 0x8a, 0xc5, 0xde }
which in the decimal is:
0 0 86 75 124 138 197 222
and you want to have:
94882212005342
which is:
94882212005342 = 0*2^56 + 0*2^48 + 86*2^40 + 75*2^32 + 124*2^24 + 138*2^16 + 197*2^8 + 222*2^0
It's a mathematical operation. You could write ex test[0] * 72057594037927936ull
but that's less readable then test[0] << 56
.
Upvotes: 2
Reputation: 49
I have done something very similar with the use of memmove or memcpy functions https://www.tutorialspoint.com/c_standard_library/c_function_memmove.htm
long long int var = 0;
memmove( &var, test, sizeof(var) );
Make sure to use the correct byte order of your system.
Upvotes: 1