簡體   English   中英

從boost :: compute :: detail :: sha1生成boost :: uuids :: uuid

[英]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::stringchar const*或適當的方法(如果這對您不理想)。)

雖然這是正確的方法,但有兩個重要注意事項:

  1. 根據RFC 4122,您需要為UUID提供名稱空間; 基本上,這是SHA1哈希的鹽。 DNS名稱,URL,ISO OID和X.500專有名稱都有預定義的名稱空間,但是由於您輸入的內容似乎與您定義自己的名稱不匹配; 如標記†所示的行,此處使用null命名空間進行說明。 可以在以下SO答案中找到有關UUID名稱空間的更詳細說明: 生成v5 UUID。 什么是名稱和名稱空間?

  2. 此代碼的輸出將與您問題中代碼的輸出完全不同; 如果您需要輸出以匹配舊代碼,則可以執行以下操作:

     #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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM