Boost 提供了一个简单的 API 来计算字符串的 SHA1 哈希:
#include <iostream>
#include <string>
#include <boost/compute/detail/sha1.hpp>
int main(int argc, char **argv)
{
if (argc < 2) {
std::cerr << "Call: " << *argv << " STR\n";
return 1;
}
boost::compute::detail::sha1 sha1 { argv[1] };
std::string s { sha1 };
std::cout << s << '\n';
return 0;
}
不过,该 API 对 Boost Compute library 是私有的,因为它是详细名称空间的一部分。这意味着它没有任何稳定性保证。
Boost 还提供了一个 SHA1 散列类作为 Boost Uuid Library 的一部分,其 API 更适合散列任意二进制输入,例如文件。虽然它是 detail 命名空间的一部分,这意味着它是一种库私有的,但它存在多年且稳定。
一个计算文件的 SHA1 哈希并将其打印到标准输出的小示例:
前奏:
#include <boost/uuid/detail/sha1.hpp>
#include <boost/predef/other/endian.h>
#include <boost/endian/conversion.hpp>
#include <boost/algorithm/hex.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <iostream>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
using namespace std;
主要功能:
{
if (argc < 2) { cerr << "Call: " << *argv << " FILE\n"; return 1; }
const char *filename = argv[1];
int fd = open(filename, O_RDONLY);
if (fd == -1) { cerr << "open: " << strerror(errno) << ")\n"; return 1; }
vector<char> v(128*1024);
boost::uuids::detail::sha1 sha1;
for (;;) {
ssize_t n = read(fd, v.data(), v.size());
if (n == -1) {
if (errno == EINTR) continue;
cerr << "read error: " << strerror(errno) << '\n';
return 1;
}
if (!n) break;
sha1.process_bytes(v.data(), n);
}
boost::uuids::detail::sha1::digest_type hash;
sha1.get_digest(hash);
#ifdef BOOST_ENDIAN_BIG_BYTE
for (unsigned i = 0; i < sizeof hash / sizeof hash[0]; ++i)
boost::endian::endian_reverse_inplace(hash[i]);
#endif
boost::algorithm::hex(boost::make_iterator_range(
reinterpret_cast<const char*>(hash),
reinterpret_cast<const char*>(hash) + sizeof hash),
std::ostream_iterator<char>(cout)); cout << '\n';
int r = close(fd);
if (r == -1) { cerr << "close error: " << strerror(errno) << '\n';
return 1; }
return 0;
}
Boost 的使用部分不会对任何 boost 共享库创建依赖关系。由于 Boost 非常便携并且可用于各种架构,因此使用 Boost 计算 SHA1 哈希值也非常便携。