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庫。