繁体   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