我需要一个 C++ 中的函数来生成与此命令在 linux 中生成的结果相似的结果。
回声-n“616161616161616”| xxd -r -p | sha256sum -b | awk '{打印 $1}'
该命令的作用是:给定一个 hexadump,将其转换为二进制文件格式,并显示二进制文件的 sha256 哈希值。xxd -r 将 hexadump 转换为二进制文件
谁能帮帮我?
首先,您应该知道您的命令行版本缺少一个半字节。即,如果你'616161616161616
通过 xxd -r -p 发送 '`,然后通过 xxd 返回,你会看到:
echo -n "616161616161616" | xxd -r -p | xxd
00000000: 6161 6161 6161 61 aaaaaaa
注意最后一个半字节6
不见了。xxd 实用程序以数字对的形式使用十六进制。一旦没有更多的对,它就会停止并发出最终输出。您可能期望将前导半字节视为单个八位字节的行为,因此是这样的:
echo -n "0616161616161616" | xxd -r -p | xxd
00000000: 0616 1616 1616 1616 ........
在任何一种情况下,无论您想如何处理,您都应该意识到这个问题。
关于您的实际问题,OpenSSL 库具有一组相当丰富的功能,可让您完成您所要求的大部分工作,几乎是微不足道的。从输入字符串计算摘要相当简单:
#include <iostream>
#include <vector>
#include <string>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
int main()
{
std::string strHex = "616161616161616"; // get this from wherever
// prepend zero-nibble for odd character counts.
if (strHex.length() % 2)
strHex.insert(strHex.begin(), '0');
// convert to blob. returns dynamic memory allocated with
// OPENSSL_malloc. Use OPENSSL_free to destroy it.
long len = 0;
unsigned char *bin = OPENSSL_hexstr2buf(strHex.c_str(), &len);
// digest the blob
const EVP_MD *md_algo = EVP_sha256();
unsigned int md_len = EVP_MD_size(md_algo);
std::vector<unsigned char> md( md_len );
EVP_Digest(bin, len, md.data(), &md_len, md_algo, nullptr);
// free the input data.
OPENSSL_free(bin);
// print the buffer to stdout in hex.
char *hexOut = OPENSSL_buf2hexstr(md.data(), md_len);
std::cout << hexOut << '\n';
OPENSSL_free(hexOut);
return 0;
}
请注意,在奇数输入长度的情况下,上面的代码采用了前置零半字节的方法。如果这不是您想要的行为(即,如果您想要与问题文本完全相同的忽略尾随奇数半字节行为),则另一种方法是修剪最后一个半字节(我严重怀疑这是您的想要的是它删除相关位并且是摘要冲突的秘诀,但是您的电话)。
#include <iostream>
#include <vector>
#include <string>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
int main()
{
std::string strHex = "616161616161616"; // get this from wherever
// prepend zero-nibble for odd character counts.
if (strHex.length() % 2)
strHex.pop_back();
// convert to blob. returns dynamic memory allocated with
// OPENSSL_malloc. Use OPENSSL_free to destroy it.
long len = 0;
unsigned char *bin = OPENSSL_hexstr2buf(strHex.c_str(), &len);
// digest the blob
const EVP_MD *md_algo = EVP_sha256();
unsigned int md_len = EVP_MD_size(md_algo);
std::vector<unsigned char> md( md_len );
EVP_Digest(bin, len, md.data(), &md_len, md_algo, nullptr);
// free the input data.
OPENSSL_free(bin);
// print the buffer to stdout in hex.
char *hexOut = OPENSSL_buf2hexstr(md.data(), md_len);
std::cout << hexOut << '\n';
OPENSSL_free(hexOut);
return 0;
}
在上述两种情况下,生成的输出都预先配置为冒号分隔的八位字节。即后一个示例输出如下所示:
E4:62:40:71:4B:5D:B3:A2:3E:EE:60:47:9A:62:3E:FB:A4:D6:33:D2:7F:E4:F0:3C:90:4B:9E:21:9A:7F:BE:60
这是由于OPENSSL_buf2hexstr
. 如果这不是您想要的(可能不是),您总是可以使用简单的查找表自己手动打印它,将每个八位字节处理为两个半字节:
#include <iostream>
#include <vector>
#include <string>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
int main()
{
std::string strHex = "616161616161616";
// prepend zero-nibble for odd character counts.
if (strHex.length() % 2)
strHex.pop_back();
// convert to blob. returns dynamic memory allocated with
// OPENSSL_malloc. Use OPENSSL_free to destroy it.
long len = 0;
unsigned char *bin = OPENSSL_hexstr2buf(strHex.c_str(), &len);
// digest the blob
const EVP_MD *md_algo = EVP_sha256();
unsigned int md_len = EVP_MD_size(md_algo);
std::vector<unsigned char> md( md_len );
EVP_Digest(bin, len, md.data(), &md_len, md_algo, nullptr);
// free the input data.
OPENSSL_free(bin);
// dump as continuous hex string
static const char alpha[] = "0123456789abcdef";
for (auto c : md)
{
std::cout << alpha[ (c >> 4) & 0xF];
std::cout << alpha[ c & 0xF];
}
std::cout.put('\n');
return 0;
}
输出
e46240714b5db3a23eee60479a623efba4d633d27fe4f03c904b9e219a7fbe60
无论如何,比我预期的要长,但希望这是你要找的。
实际算法取决于您想要做什么 - 您可以将十六进制转换为字符串。我在下面的例子中做到了。
您首先要做的是将字符串转换为二进制,这可以通过以下方式完成:
std::string toBin(std::string str){
int s = str.length();
std::string bin = ""
for (int i = 0; i <= n; i++){
int v = int(s[i]);
while (val > 0){
(val % 2)? bin.push_back('1') : bin.push_back('0');
val /= 2;
}
}
std::reverse(bin.begin(), bin.end());
}
但是,代码的下一部分太长了,遗憾的是我无法将其包含在此答案中。但我会将您链接到一个包含(希望)您需要的所有代码的网站。http://www.zedwood.com/article/cpp-sha256-function
最好的祝愿。