【问题标题】:Unsigned char to hexstring and back but results don't match无符号字符到十六进制字符串并返回,但结果不匹配
【发布时间】:2021-09-27 14:19:30
【问题描述】:

我有一个长度为 32 的无符号字符数组 c1。

unsigned char c1[32]

现在我有了一个加密函数,细节很长。基本上这个加密只是给c1加了一些值。

encrypt(&c1,private_key,public_key,message);

现在我有以下代码可以将其转换为十六进制字符串:

printf("Initial value is %02x",c1);
char *sit = malloc(sizeof c1 * 2 + 1);
     for (size_t i = 0; i < sizeof c1; i++)
     { sprintf(sit + i * 2, "%02x", c1[i]);
       
     } 

现在我尝试取回 unsigned char 数组:

unsigned char recvalue[32];
     for(int i=0;i<32;i++)
          {
             unsigned testchar=0;
             sscanf(&sit[i*2],"%02x",&testchar);
             recvalue[i]=(unsigned char)testchar;
          }
printf("The final value is %02x",recvalue);

现在这里的 c1 和 recvalue 的值不匹配,但我需要它们匹配。任何帮助将不胜感激。

【问题讨论】:

  • i &lt; sizeof c1 这看起来不对。 sizeof c1 是以字节为单位的数组大小(假设它是一个实际数组而不是动态内存缓冲区),而不是数组中的条目数。如需进一步帮助,请提供完整代码minimal reproducible example
  • 确实如此。但是从代码中并不清楚,因为您没有显示定义。请按要求提供完整的代码。如果您想质疑为什么需要这样做,请阅读链接。
  • printf 语句不打印数组的内容。他们只是打印每个人的地址。你需要遍历它们。
  • printf("The final value is %02x",&amp;recvalue); 我相信你的意思是*recvalue 不是&amp;recvalue。同样,正如@dbush 指出的那样,如果您打算打印需要循环的整个内容。
  • @ArnabGhosh 它们不应该匹配,因为您正在打印两个单独数组的地址(并且不正确)。你想遍历每一个并打印内容。

标签: c char unsigned


【解决方案1】:

%02x(或%02X)格式的printf 至少打印所提供整数的两位数。它类似于%u,但将打印以十六进制为基数的值。但是,你给它一个数组的地址。 您似乎将它与 %s 格式混淆了,您实际上给出了字符串的初始地址,它将打印整个字符串。 %02x 不同。它需要一个整数值。 索引数组,这样你就可以给它实际的字节值:

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

int main()
{
    unsigned char c1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                            0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00,
                            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
                            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 };

    char *sit = malloc(sizeof c1 * 2 + 1);
    for (size_t i = 0; i < sizeof c1; i++)
    {
        sprintf(sit + i * 2, "%02x", c1[i]);
    }

    printf("Initial value is: ");
    for (size_t i = 0; i < sizeof c1; i++)
        printf("%02X ", c1[i]);
    printf("\n");

    printf("sit is: %s\n", sit);

    unsigned char recvalue[32];
    for(int i=0;i<32;i++)
    {
       unsigned testchar=0;
       sscanf(&sit[i*2],"%02x",&testchar);
       recvalue[i]=(unsigned char)testchar;
    }

    printf("The final value is: ");
    for (size_t i = 0; i < sizeof recvalue; i++)
        printf("%02X ", recvalue[i]);
    printf("\n");

    return 0;
}

输出:

Initial value is: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20  
sit is: 0102030405060708090a0b0c0d0e0f001112131415161718191a1b1c1d1e1f20
The final value is: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20  

【讨论】:

  • 替代unsigned testchar=0; sscanf(&amp;sit[i*2],"%02x",&amp;testchar); recvalue[i]=(unsigned char)testchar; --> sscanf(&amp;sit[i*2],"%2hhx",&amp;recvalue[i]);
  • hhx 会更好地反映给定的值。感谢我刚刚在手册页中查看的建议,坦率地说不知道。当然也不需要临时变量……代码越少越好!
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 2011-07-22
  • 1970-01-01
  • 2015-04-24
  • 2010-10-04
  • 2014-03-07
  • 2016-03-08
  • 2016-11-07
相关资源
最近更新 更多