[This question关于如何使用OpenSSL库从C中的数据数组创建SHA-1哈希。
它返回一个20字节的数组,其中包含哈希。是否有某种标准的方式以字符串形式而不是二进制形式表示该数据?
如果是这样,OpenSSL本身是否有一个函数可以转换为所述字符串格式?
如果没有,应该怎么做?当然,我可以幻想自己的编码,使用base64或其他,但是有一些规范的格式吗?
通常将散列表示为十六进制数字的序列(自然地,每个字节两个)。您可以使用带有正确修饰符的ostringstream
编写代码来轻松编写此类代码:
#include <string>
#include <sstream>
#include <iomanip>
std::string GetHexRepresentation(const unsigned char *Bytes, size_t Length) {
std::ostringstream os;
os.fill('0');
os<<std::hex;
for(const unsigned char *ptr = Bytes; ptr < Bytes+Length; ++ptr) {
os<<std::setw(2)<<(unsigned int)*ptr;
}
return os.str();
}
可以说,这也可以通过“手动”更有效地完成(并且在我今天的眼中更加清楚):
#include <string>
std::string GetHexRepresentation(const unsigned char *Bytes, size_t Length) {
std::string ret(Length*2, '\0');
const char *digits = "0123456789abcdef";
for(size_t i = 0; i < Length; ++i) {
ret[i*2] = digits[(Bytes[i]>>4) & 0xf];
ret[i*2+1] = digits[ Bytes[i] & 0xf];
}
return ret;
}
或具有良好的旧sprintf
,可能是所有方法中最容易阅读的方法:
#include <stdio.h>
#include <string>
std::string GetHexRepresentation(const unsigned char *Bytes, size_t Length) {
std::string ret;
ret.reserve(Length * 2);
for(const unsigned char *ptr = Bytes; ptr < Bytes+Length; ++ptr) {
char buf[3];
sprintf(buf, "%02x", (*ptr)&0xff);
ret += buf;
}
return ret;
}
表示哈希的标准方法是使用十六进制字符串。在C语言中,您可以使用printf("%02x", byte)
获取每个字节的十六进制表示形式。
MD5的示例,应该很容易使其适应SHA:
这里是C的示例:
//function
void convertSHA1BinaryToCharStr(const unsigned char * const hashbin, char * const hashstr) {
for(int i = 0; i<20; ++i)
{
sprintf(&hashstr[i*2], "%02X", hashbin[i]);
}
hashstr[40]=0;
}
//Example call. hashbin is the 20byte hash array.
char hashstr[41];
convertSHA1BinaryToCharStr(hashbin, hashstr);
printf("%s\n", hashstr);
隐私增强邮件(或PEM)似乎为加密数据的文本表示的存储设置了标准。PEM将实际的二进制块存储在Base64中,但也具有文本页眉和页脚。