【发布时间】:2020-12-06 09:09:34
【问题描述】:
我正在尝试将十六进制字符串转换为二进制,稍后将传递给加密库(openssl AES EVP_xx),所以我想我只需要一个带有 nul 终止符的二进制字符串。
我使用了Josch 演示的第二个测试 他的测试用例非常强大,所以我最终使用了查找表。 我只是更改了输入变量并添加了打印,但总是打印垃圾。
我只添加了以下内容:
-
malloc(期望的二进制字符串长度 + 1)
-
在循环结束时设置 nul 终止符。 AFAIK 当字符串不是空终止时返回这些垃圾字符。
#include <string.h> #include <stdio.h> #include <stdlib.h> /* the resulting binary string is half the size of the input hex string * because every two hex characters map to one byte */ unsigned char base16_decoding_table1[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}; int main(int argc, char **argv){ int TESTDATALEN=strlen(( char*) argv[1]); //char *result=malloc((TESTDATALEN/2)+1); int mallocLen=(TESTDATALEN%2) ? ((TESTDATALEN+3)/2) : ((TESTDATALEN/2)+1); unsigned char *result=malloc(mallocLen); *result='\0'; int i; unsigned char cur; unsigned char val; for (i = 0; i < TESTDATALEN; i++) { cur = argv[1][i]; val = base16_decoding_table1[(int)cur]; /* even characters are the first half, odd characters the second half * of the current output byte */ if (i%2 == 0) { result[i/2] = val << 4; } else { result[i/2] |= val; } } result[mallocLen] = '\0'; printf ("Binary value: %s\n", result); //for (i = 0; i < TESTDATALEN/2; i++) printf ("%02hhx", result[i]); //putchar ('\n'); free(result); return 0; }
如果相关,我可能会在上下文中添加更多内容;出于性能原因,我无法触摸 strcat,因为十六进制到二进制只是加密中的一个步骤,它在数千(或数百万)个输入上执行,单个字段可以达到 8kb,因此也不能使用 strtol 并且必须这样做它在字符串中,
当前输出为:
hex2bin1.6.2 abc123def789
��#�
虽然此值的二进制等效项是: 101010111100000100100011110111101111011110001001
目标是将此转换代码返回的二进制字符串提供给 openssl AES EVP 加密例程,该例程接受并返回二进制输入。
提前致谢
【问题讨论】:
-
嗯,您的代码看起来像working well。
-
这里至少有两个基本错误。一是您的输出缓冲区太小(当输入字符串的长度为奇数时,它会减一)。其次是
char可能已签名,所以base_decoding_table[(int)cur]可能超出范围。从风格上讲,你做了很多漫无目的的演员表。如果您提供一个失败的硬编码示例字符串以及您期望的输出,您的问题也会更好。 -
你
#include "base_encoding_table.h"但问题中没有提供。这也可能是问题的根源。 -
为什么是
printf ("Binary value: %s\n", result);而不是for (i = 0; i < TESTDATALEN/2; i++) printf ("%02hhx", result[i]); putchar ('\n');?result可能是char类型并以 nul 结尾——但它肯定不包含 ASCII 字符值...... -
@MikeCAT 感谢您的测试,输出仍然是符号,我需要 0 和 1;我在最后添加了更好的解释
标签: c