如何将 unsigned char* 转换为 unsigned long long int?

时间:2021-03-12 13:08:56

标签: c type-conversion built-in unsigned-char unsigned-long-long-int

有谁知道提供执行此逻辑的函数或执行此逻辑的方法的库吗?​​

我正在尝试转换:

unsigned char test[] = "\x00\x00\x56\x4b\x7c\x8a\xc5\xde";

到:

94882212005342 / 0x0000564b7c8ac5de

我知道我可以遍历 test 中的每个单独的字节并利用 sprintf 将每个字节转换为字符串,并使用 strcat 将它们连接到一个缓冲区中并转换缓冲区字符串通过 unsigned long longstrtoull。但是,我正在寻找更全面和更简单的东西。有这种方法吗?

4 个答案:

答案 0 :(得分:2)

这只是数学。

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

答案 1 :(得分:1)

我使用 memmove 或 memcpy 函数做了一些非常相似的事情https://www.tutorialspoint.com/c_standard_library/c_function_memmove.htm

    long long int var = 0; 
    memmove( &var, test, sizeof(var) );

确保使用正确的系统字节顺序。

答案 2 :(得分:0)

只是为了记录,你可以简单地这样做:

#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);
}

答案 3 :(得分:-1)

一种有趣但不推荐的方法。如果您想要一个合适的解决方案,请查看 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);
}

请注意,标准并未规定字节顺序。这在我的机器上有效。它在大多数机器上都是一样的,但如果对其他架构的可移植性对您很重要。甚至不要考虑这个。

但是,由于您说值是地址,我建议使用 uintptr_t 而不是 long

相关问题