[英]Generate boost::uuids::uuid from boost::compute::detail::sha1
我試圖以這種方式從boost :: compute :: detail :: sha1生成boost :: uuids :: uuid :
#include <iostream>
#include "boost/uuid/uuid.hpp"
#include "boost/uuid/uuid_io.hpp"
#include "boost/uuid/string_generator.hpp"
#include "boost/compute/detail/sha1.hpp"
int main(int argc, char* argv[])
{
try
{
boost::compute::detail::sha1 sha1("b888e35f9edf3794760392e1066d69-f43d-452e-8475-a09bae9a2e8500000000-0000-0000-0000-000000000000");
std::string str = sha1;
boost::uuids::uuid uuid = boost::uuids::string_generator()(str); // ERROR HERE!!
}
catch (std::exception& e)
{
std::cerr << "Error occurred: " << e.what() << std::endl;
}
return 0;
}
但是此代碼失敗,並顯示以下Error occurred: invalid uuid string
(請參見上文)
我正在使用Visual Studio 2017 Boost 1.67
我的錯誤在哪里? 如何從boost :: compute :: detail :: sha1生成boost :: uuids :: uuid
PS:該代碼適用於以前的Boost版本。
從任意字符串的SHA1哈希中獲取UUID的正確的受支持方法如下:
#include <string_view>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/name_generator_sha1.hpp>
boost::uuids::uuid uuid_from_string(std::string_view const input) {
static constexpr boost::uuids::uuid ns_id{}; // †null root, change as necessary
return boost::uuids::name_generator_sha1{ns_id}(input.data(), input.size());
}
( std::string_view
用於說明;使用std::string
或char const*
或適當的方法(如果這對您不理想)。)
雖然這是正確的方法,但有兩個重要注意事項:
根據RFC 4122,您需要為UUID提供名稱空間; 基本上,這是SHA1哈希的鹽。 DNS名稱,URL,ISO OID和X.500專有名稱都有預定義的名稱空間,但是由於您輸入的內容似乎與您定義自己的名稱不匹配; 如標記†所示的行,此處使用null命名空間進行說明。 可以在以下SO答案中找到有關UUID名稱空間的更詳細說明: 生成v5 UUID。 什么是名稱和名稱空間?
此代碼的輸出將與您問題中代碼的輸出完全不同; 如果您需要輸出以匹配舊代碼,則可以執行以下操作:
#include <cstring> #include <string_view> #include <boost/endian/conversion.hpp> #include <boost/uuid/uuid.hpp> #include <boost/uuid/detail/sha1.hpp> boost::uuids::uuid uuid_from_string_old(std::string_view const input) { boost::uuids::detail::sha1::digest_type digest; { boost::uuids::detail::sha1 h; h.process_bytes(input.data(), input.size()); h.get_digest(digest); } boost::uuids::uuid ret; auto p = ret.begin(); for (std::size_t i{}; i != 4; p += 4, ++i) { auto const d = boost::endian::native_to_big(digest[i]); std::memcpy(p, &d, 4); } return ret; }
從使用帶有Boost 1.65.1的舊代碼的演示中可以看出,這產生了相同的輸出。 這違反了我從未直接使用別人的detail
名稱空間的評論政策,但是除非您能找到魔術名稱空間ID(如果存在),否則這是我所知道的唯一使用Boost的方法。 Nb修復了舊的Boost-big-endian機器中的錯誤。 如果您需要保留該錯誤,請將調用boost::endian::native_to_big
改為調用boost::endian::endian_reverse
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.