如何在十六进制中将uint_64的十六进制表示复制到unsigned char数组?

时间:2016-12-16 11:09:55

标签: c arrays uint64

我不确定如何用言语表达我想要实现的目标,但我只是在下面举一个例子,希望你们能帮助我!

基本上我试图将uint64_t值的十六进制表示复制到十六进制的unsigned char数组中。

我有什么:

uint64_t src;
unsigned char destination[8];
/* codes omitted, some codes that will change the value of src */
printf("src: %"PRIx64"\n", src); //this prints out src: 3132333435363738

如何将src中的值复制到目标数组中:

destination[0] = 0x31;
destination[1] = 0x32;
destination[2] = 0x33;
//and so on...

谢谢!

修改

对不起如果我的问题不清楚,我对编程很陌生,而且我很难解释自己。 基本上我只是试图将那些从printf()打印出来的内容存储到unsigned char数组中作为hex。

例如,printf()输出一个字符串" 3132333435363738",我想取31并将其存储在dst [0]中,其中dst [0]的值将为0x31,依此类推,其中dst [1]为0x32。

请耐心等待,谢谢!

4 个答案:

答案 0 :(得分:3)

以给定顺序提取构成整数的字节的简单且可移植的方法是仅使用位移(以及可能的掩码);在你的情况下,你似乎想要以big-endian顺序提取你的字节(destination => src中最重要的字节的第一个字节),所以这将是:

uint64_t src;
unsigned char destination[8];
for(int i=0; i<8; ++i) {
    destination[i] = src>>((7-i)*8);
} 

在每次迭代时,src向右移动(7-i)* 8位,因为我们希望所需的字节位于结果的“底部”

第一次迭代:

src = 0x123456789abcdef0;
i = 0
(7-i) = 7
src >> ((7-i)*8) = 0x12

所以,我们得到了0x12,我们将它放入destination[0];在下一次迭代中,我们有

i = 1
(7-i) = 6
src >> ((7-i)*8) = 0x1234

现在,我们可以用0xFF 掩盖结果,只取底部的8位(即0x34),但这在我们的情况下并不重要,因为{{{{1} 1}}是一个无符号字节,因此当分配大于255的值时(如本例所示),它会执行无符号溢出,这很好地定义为仅采用“适合”目标的较低字节;所以,destination

destination[1]=0x34重复此操作,最多7个,您将获得所需的结果。

答案 1 :(得分:0)

您可以设置指针指向C:\Users\user\Desktop\myApp>typings install node express body-parser serve-static dexpress-serve-static-core mime --global --save typings INFO globaldependencies "express" lists global dependencies on "node" that must be installed manually typings INFO globaldependencies "serve-static" lists global dependencies on "node" that must be installed manually typings INFO globaldependencies "body-parser" lists global dependencies on "node" that must be installed manually typings ERR! message Unable to find "node" ("npm") in the registry. typings ERR! message However, we found "node" for 2 other sources: "dt" and "env" typings ERR! message You can install these using the "source" option. typings ERR! message We could use your help adding these typings to the registry: https://github.com/typings/registry typings ERR! caused by https://api.typings.org/entries/npm/node/versions/latest responded with 404, expected it to equal 200 typings ERR! typings ERR! cwd C:\Users\user\Desktop\myApp typings ERR! system Windows_NT 10.0.14393 typings ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\user\\AppData\\Roaming\\npm\\node_modules\\typings\\dist\\bin.js" "install" "node" "express" "body-parser" "serve-static" "dexpress-serve-static-core" "mime" "--global" "--save" typings ERR! node -v v6.9.2 typings ERR! typings -v 2.0.0 typings ERR! typings ERR! If you need help, you may report this error at: typings ERR! <https://github.com/typings/typings/issues> 本身:

uint64_t

如果您需要复制该值,而不仅仅是另一个视图,则适用相同的原则:

uint64_t src;
unsigned char *view;

view = (unsigned char *)&src;
for (size_t i = 0; i < sizeof(src); ++i) {
  printf("%x", view[i]);
}
printf("\n");

请注意,这将继承平台的本机字节顺序。如果要转换字节顺序,可以在查看/复制字符串之前在uint64_t src; unsigned char dst[sizeof(src)]; memcpy((void *)&dst, (void *)&src, sizeof(src)); for (size_t i = 0; i < sizeof(src); ++i) { printf("%x", dst[i]); } printf("\n"); 上使用库函数uint64_t htobe64(uint64_t x)(Linux,BSD)或OSSwapHostToBigInt64(x)(OS X)。我不知道Windows的等价物,但我认为他们有。请参阅我使用src而不是unsigned char来避免任何符号扩展问题。

答案 2 :(得分:0)

使用指针强制转换+指针算法的解决方案或使用联合的解决方案将无法移植。

这是一种简单的方法来实现这一点,无论结束。可能有更有效的方法。

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdbool.h>

int main(void)
{
  uint64_t src;
  uint8_t destination[8] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};

  const uint16_t dummy = 1;
  const bool is_little_endian = *(const uint8_t*)&dummy == 1;

  src=0;
  for(size_t i=0; i<8; i++)
  {
    size_t shift = i*8;

    if(is_little_endian)
    {
      shift = 64-8-shift;
    }

    src |= (uint64_t)destination[i] << shift;
  }

  printf("%" PRIx64, src);

  return 0;
}

答案 3 :(得分:0)

这与@Matteo Italia给出的解决方案基本相同,但使用掩码和显式强制转换为固定宽度类型uint8_t而不是unsigned char。无论字节顺序如何,这些解决方案都应该有效,因为按位运算符处理左操作数的值,而不是它的基础表示。

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    uint64_t src = 0x3132333435363738;
    uint8_t destination[8];
    uint64_t mask = 0xff << 56;
    size_t i;

    for (i = 0; i < 8; i++) {
        destination[i] = (uint8_t) ((src & mask) >> (56 - i * 8));
        mask >>= 8;
    }

    printf("src: 0x%" PRIx64 "\n", src);

    for (i = 0; i < 8; i++) {
        printf("destination[%zu] = 0x%" PRIx8 "\n", i, destination[i]);
    }

    return 0;
}

输出是:

src: 0x3132333435363738
destination[0] = 0x31
destination[1] = 0x32
destination[2] = 0x33
destination[3] = 0x34
destination[4] = 0x35
destination[5] = 0x36
destination[6] = 0x37
destination[7] = 0x38