如何将OpenSSL HMAC SHA256的32字节输出转为64字节字符串?
解决方案
你需要将32字节的二进制HMAC-SHA256哈希值转换成十六进制字符串——这正是你那段printf代码的核心逻辑:每个字节被格式化为两位大写十六进制字符,32×2刚好是64字节的字符串(不含终止符)。Base64是完全不同的编码方式,自然会得到不符的结果,别再用它了。
实现方式一:用sprintf逐个拼接
直接模仿printf的格式化逻辑,把每个字节的十六进制结果写入字符串缓冲区:
#include <stdio.h> #include <stdlib.h> // 传入已生成的32字节哈希缓冲区result,以及长度result_len(固定为32) char* hash_to_hex(unsigned char* result, size_t result_len) { // 每个字节占2个字符,额外加1位存储字符串终止符'\0' char* hex_str = malloc(result_len * 2 + 1); if (!hex_str) return NULL; for (size_t i = 0; i < result_len; i++) { // 将单个字节格式化为两位大写十六进制,写入对应位置 sprintf(hex_str + i*2, "%02X", result[i]); } hex_str[result_len * 2] = '\0'; return hex_str; }
调用后,hex_str就是你需要的64字节(不含终止符)的目标字符串,使用完毕记得用free(hex_str)释放内存。
实现方式二:手动字符转换(性能更优)
避免多次调用sprintf的开销,直接通过位运算和字符映射表生成结果:
#include <stdlib.h> // 大写十六进制字符映射表 static const char hex_chars[] = "0123456789ABCDEF"; char* hash_to_hex_fast(unsigned char* result, size_t result_len) { char* hex_str = malloc(result_len * 2 + 1); if (!hex_str) return NULL; char* ptr = hex_str; for (size_t i = 0; i < result_len; i++) { // 提取字节的高4位,映射到对应十六进制字符 *ptr++ = hex_chars[(result[i] >> 4) & 0x0F]; // 提取字节的低4位,映射到对应十六进制字符 *ptr++ = hex_chars[result[i] & 0x0F]; } *ptr = '\0'; return hex_str; }
这个方法的执行效率更高,输出结果和第一种方式完全一致,适合对性能有要求的场景。
关键说明
- 你对接的接口要求的"64字节SHA256哈希",本质是十六进制编码后的字符串,SHA256的二进制哈希长度固定为32字节,不存在64字节的二进制哈希。
- 十六进制编码和Base64编码规则完全不同:前者1字节对应2个字符,后者3字节对应4个字符,所以用Base64编码必然得不到符合要求的64字节结果。
内容的提问来源于stack exchange,提问作者bicoi77
相关产品推荐
相关产品推荐

