如何将 unsigned char* 转换为 unsigned long long int?
How to convert unsigned char* to unsigned long long int?
有谁知道提供执行此逻辑的函数或执行此逻辑的方法的库吗?
我正在尝试转换:
unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";
至:
94882212005342 / 0x0000564b7c8ac5de
我知道我可以遍历 test
中的每个单独字节并利用 sprintf
将每个字节转换为字符串并将它们连接到带有 strcat
的缓冲区中并转换通过 strtoull
将字符串缓冲到 unsigned long long
。但是,我正在寻找更全面和简单的东西。有这样的方法吗?
这只是数学。
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;
记得在移动之前强制转换为足够宽的类型。
您有 8 个值:
{ 0x00, 0x00, 0x56, 0x4b, 0x7c, 0x8a, 0xc5, 0xde }
小数点是:
0 0 86 75 124 138 197 222
你想要:
94882212005342
即:
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
这是一个数学运算。你可以写 ex test[0] * 72057594037927936ull
但这比 test[0] << 56
.
可读性差
我用 memmove 或 memcpy 函数做了一些非常相似的事情 https://www.tutorialspoint.com/c_standard_library/c_function_memmove.htm
long long int var = 0;
memmove( &var, test, sizeof(var) );
确保使用正确的系统字节顺序。
一种有趣但不推荐的方法。如果你想要一个合适的解决方案,请查看
#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);
}
请注意,标准并未规定字节顺序。这就是我的机器上的工作原理。它在大多数机器上都是一样的,但如果对其他体系结构的可移植性对您很重要。别想了。
但是,既然你说的是地址,我建议使用 uintptr_t
而不是 long
。
郑重声明,您可以简单地这样做:
#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);
}
有谁知道提供执行此逻辑的函数或执行此逻辑的方法的库吗?
我正在尝试转换:
unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";
至:
94882212005342 / 0x0000564b7c8ac5de
我知道我可以遍历 test
中的每个单独字节并利用 sprintf
将每个字节转换为字符串并将它们连接到带有 strcat
的缓冲区中并转换通过 strtoull
将字符串缓冲到 unsigned long long
。但是,我正在寻找更全面和简单的东西。有这样的方法吗?
这只是数学。
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;
记得在移动之前强制转换为足够宽的类型。
您有 8 个值:
{ 0x00, 0x00, 0x56, 0x4b, 0x7c, 0x8a, 0xc5, 0xde }
小数点是:
0 0 86 75 124 138 197 222
你想要:
94882212005342
即:
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
这是一个数学运算。你可以写 ex test[0] * 72057594037927936ull
但这比 test[0] << 56
.
我用 memmove 或 memcpy 函数做了一些非常相似的事情 https://www.tutorialspoint.com/c_standard_library/c_function_memmove.htm
long long int var = 0;
memmove( &var, test, sizeof(var) );
确保使用正确的系统字节顺序。
一种有趣但不推荐的方法。如果你想要一个合适的解决方案,请查看
#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);
}
请注意,标准并未规定字节顺序。这就是我的机器上的工作原理。它在大多数机器上都是一样的,但如果对其他体系结构的可移植性对您很重要。别想了。
但是,既然你说的是地址,我建议使用 uintptr_t
而不是 long
。
郑重声明,您可以简单地这样做:
#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);
}