C ++ 17的跨平台单头库实现了普遍唯一的标识符,只是仅知道是UUID或GUID(主要是在Windows上)。 UUID是一个128位编号,用于在计算机系统中唯一识别信息,例如数据库表键,COM接口,类和类型库等。
有关UUID/GUID的信息,请参见:
尽管该规范将UUID库放在std名称空间中,但此实现为此目的使用了名称空间uuids ,以使库可用而不违反在std名称空间上施加的限制。可用以下类型和实用程序:
基本类型:
| 姓名 | 描述 |
|---|---|
uuid | 代表UUID的课程;可以默认构造(一个由范围(由一对迭代器定义)构建的nil UUID),也可以从span构建。 |
uuid_variant | 代表UUID类型的强烈枚举 |
uuid_version | 强烈的枚举,代表UUID的版本 |
发电机:
| 姓名 | 描述 |
|---|---|
basic_uuid_random_generator | 使用伪随机数生成器引擎生成版本4 UUID的函数对象。 |
uuid_random_generator | 使用Mersenne Twister Engine( basic_uuid_random_generator<std::mt19937> )的basic_uuid_random_generator |
uuid_name_generator | 使用SHA1哈希生成版本5,基于名称的UUID的函数对象。 |
uuid_system_generator | 一个使用操作系统资源生成新UUID的功能对象(Windows上的CoCreateGuid , uuid_generate在linux上,mac上的CFUUIDCreate )注意:这不是标准建议的一部分。仅当定义了 UUID_SYSTEM_GENERATOR宏时才可用。 |
uuid_time_generator | 生成基于时间的UUID的实验函数对象。 注意:这是一个实验功能,不应在任何生产代码中使用。仅当定义了 UUID_TIME_GENERATOR宏时才可用。 |
公用事业:
| 姓名 | 描述 |
|---|---|
std::swap<> | 专业swap的uuid |
std::hash<> | 对uuid的hash (将UUID存储在无序的关联容器中,例如std::unordered_set ) |
常数:
| 姓名 | 描述 |
|---|---|
uuid_namespace_dns | 当名称字符串是一个完全合格的域名时,基于名称的UUID的名称空间ID。 |
uuid_namespace_url | 当名称字符串是URL时,基于名称的UUID的命名空间ID。 |
uuid_namespace_oid | 当Mame String是ISO OID时,基于名称的UUID的命名空间ID(请参阅https://oidref.com/,https://en.wikipedia.org/wiki/object_identifier)。 |
uuid_namespace_x500 | 当名称字符串为X.500 DN时,命名空间ID(以DER或文本输出格式)(请参阅https://en.wikipedia.org/wiki/wiki/x.500,https://en.wikipedia.org/wiki.org/wiki/abstract_stract_stract_stract_stract_sytax_notation_notation_notation_one_one_one_one_one)。 |
其他:
| 姓名 | 描述 |
|---|---|
operator==和operator!= | 用于平等/不平等的UUID比较 |
operator< | 要比较一个uuids是否比另一个uuids少。尽管此操作没有太大的逻辑意义,但为了将UUID存储在std ::设置中是必要的。 |
operator<< | 使用规范文本表示为输出流编写一个UUID。 |
to_string() | 使用UUID的规范文本表示创建一个字符串。 |
该库是提案P0959的实施。
随着提案根据标准委员会和C ++社区反馈的发展,该图书馆的实施将反映这些变化。
请参阅《变革史提案的修订历史》。
以下是使用库的示例列表:
创建一个nil uuid
uuid empty;
assert (empty.is_nil());创建一个新的UUID
uuid const id = uuids::uuid_system_generator{}();
assert (!id.is_nil());
assert (id.version() == uuids::uuid_version::random_number_based);
assert (id.variant() == uuids::uuid_variant::rfc);使用默认随机生成器创建新的UUID
std::random_device rd;
auto seed_data = std::array< int , std::mt19937::state_size> {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::mt19937 generator (seq);
uuids::uuid_random_generator gen{generator};
uuid const id = gen();
assert (!id.is_nil());
assert (id.as_bytes().size() == 16);
assert (id.version() == uuids::uuid_version::random_number_based);
assert (id.variant() == uuids::uuid_variant::rfc);使用特定的随机生成器创建新的UUID
std::random_device rd;
auto seed_data = std::array< int , 6 > {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::ranlux48_base generator (seq);
uuids::basic_uuid_random_generator<std::ranlux48_base> gen (&generator);
uuid const id = gen();
assert (!id.is_nil());
assert (id.as_bytes().size() == 16);
assert (id.version() == uuids::uuid_version::random_number_based);
assert (id.variant() == uuids::uuid_variant::rfc);使用名称生成器创建新的UUID
uuids::uuid_name_generator gen (uuids::uuid::from_string( " 47183823-2574-4bfd-b411-99ed177d3e43 " ).value());
uuid const id = gen( " john " );
assert (!id.is_nil());
assert (id.version() == uuids::uuid_version::name_based_sha1);
assert (id.variant() == uuids::uuid_variant::rfc);用字符串创建一个UUID
auto str = " 47183823-2574-4bfd-b411-99ed177d3e43 " s;
auto id = uuids::uuid::from_string(str);
assert (id.has_value());
assert (uuids::to_string(id.value()) == str);
// or
auto str = L" 47183823-2574-4bfd-b411-99ed177d3e43 " s;
uuid id = uuids::uuid::from_string(str).value();
assert (uuids::to_string< wchar_t >(id) == str);从16个字节的序列创建一个UUID
std::array<uuids::uuid::value_type, 16 > arr{{
0x47 , 0x18 , 0x38 , 0x23 ,
0x25 , 0x74 ,
0x4b , 0xfd ,
0xb4 , 0x11 ,
0x99 , 0xed , 0x17 , 0x7d , 0x3e , 0x43 }};
uuid id (arr);
assert (uuids::to_string(id) == "47183823-2574-4bfd-b411-99ed177d3e43");
// or
uuids::uuid::value_type arr[ 16 ] = {
0x47 , 0x18 , 0x38 , 0x23 ,
0x25 , 0x74 ,
0x4b , 0xfd ,
0xb4 , 0x11 ,
0x99 , 0xed , 0x17 , 0x7d , 0x3e , 0x43 };
uuid id (std::begin(arr), std::end(arr));
assert (uuids::to_string(id) == "47183823-2574-4bfd-b411-99ed177d3e43");
// or
uuids::uuid id{{
0x47 , 0x18 , 0x38 , 0x23 ,
0x25 , 0x74 ,
0x4b , 0xfd ,
0xb4 , 0x11 ,
0x99 , 0xed , 0x17 , 0x7d , 0x3e , 0x43 }};
assert (uuids::to_string(id) == "47183823-2574-4bfd-b411-99ed177d3e43");比较UUID
uuid empty;
uuid id = uuids::uuid_system_generator{}();
assert (empty == empty);
assert (id == id);
assert (empty != id);交换UUID
uuid empty;
uuid id = uuids::uuid_system_generator{}();
assert (empty.is_nil());
assert (!id.is_nil());
std::swap (empty, id);
assert (!empty.is_nil());
assert (id.is_nil());
empty.swap(id);
assert (empty.is_nil());
assert (!id.is_nil());转换为字符串
uuid empty;
assert (uuids::to_string(empty) == "00000000-0000-0000-0000-000000000000");
assert (uuids::to_string< wchar_t >(empty) == L"00000000-0000-0000-0000-000000000000");与有订购的关联容器一起使用
std::random_device rd;
auto seed_data = std::array< int , std::mt19937::state_size> {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::mt19937 engine (seq);
uuids::uuid_random_generator gen (&engine);
std::set<uuids::uuid> ids{uuid{}, gen (), gen (), gen (), gen ()};
assert (ids.size() == 5);
assert (ids.find(uuid{}) != ids.end());在无序的关联容器中
std::random_device rd;
auto seed_data = std::array< int , std::mt19937::state_size> {};
std::generate (std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq (std::begin(seed_data), std::end(seed_data));
std::mt19937 engine (seq);
uuids::uuid_random_generator gen (&engine);
std::unordered_set<uuids::uuid> ids{uuid{}, gen (), gen (), gen (), gen ()};
assert (ids.size() == 5);
assert (ids.find(uuid{}) != ids.end());哈希uuids
using namespace std ::string_literals ;
auto str = " 47183823-2574-4bfd-b411-99ed177d3e43 " s;
uuid id = uuids::uuid::from_string(str).value();
auto h1 = std::hash<std::string>{};
auto h2 = std::hash<uuid>{};
assert (h1(str) == h2(id));如果使用basic_uuid_random_generator和std :: Random_device生成UUID,请记住,这可能不是非确定性的,并且实际上会生成相同的数字序列:
如果非确定性源(例如,硬件设备)无法实现,则可以根据实现定义的伪随机编号引擎实现std :: Random_device。在这种情况下,每个std :: Random_device对象可能会生成相同的数字序列。
这可能是mingw的问题。请参阅错误85494-在mingw上实现Random_device是没有用的。这是在GCC 9.2中固定的。
便携式替代方法是使用boost.random库。
该库在所有主要操作系统上都支持:Windows,Linux和Mac OS。
如果您在使用C ++ 20构建的项目中使用库,则可以使用std::span 。默认情况下,如果标题由编译器支持,则使用。使用__CPP_LIB_SPAN特征测试宏进行检查。
否则,例如使用C ++ 17构建时, std::span不可用。但是,Microsoft指南支持库(又称GSL)可用于其span实现(从中定义了标准版本)。如果std::span不可用,则stduuid库将使用此实现。
为了确保可以使用gsl::span ,请确保GSL库可用,并且GSL Incluber Directory在项目的包含目录中列出了Directory。
如果使用CMAKE构建测试项目,请确保未定义称为UUID_USING_CXX20_SPAN的变量,或者其值已OFF (这是默认值)。这将确保gsl目录将包含在标题目录的搜索列表中。
来源有一个测试项目。为了构建和执行测试,请执行以下操作:
build目录build目录运行命令cmake .. ;如果您没有CMAKE,则必须先安装它。例子
要为Visual Studio 2019生成项目文件,您可以运行以下命令:
cd build
cmake -G "Visual Studio 17" -A x64 ..
要启用操作系统uuid发电机将UUID_SYSTEM_GENERATOR变量设置为ON 。
cd build
cmake -G "Visual Studio 17" -A x64 -DUUID_SYSTEM_GENERATOR=ON ..
要启用基于实验的UUID生成器,将UUID_TIME_GENERATOR变量设置为ON 。
cd build
cmake -G "Visual Studio 17" -A x64 -DUUID_TIME_GENERATOR=ON ..
SHA1实现基于Tinysha1库。