การใช้งานไลบรารีส่วนหัวแบบข้ามแพลตฟอร์ม C ++ 17 สำหรับตัวระบุที่ไม่ซ้ำกันในระดับสากล UUID คือหมายเลข 128 บิตที่ใช้ในการระบุข้อมูลในระบบคอมพิวเตอร์เช่นปุ่มตารางฐานข้อมูลอินเตอร์เฟส COM คลาสและไลบรารีประเภทและอื่น ๆ อีกมากมาย
สำหรับข้อมูลเกี่ยวกับ UUID/GUID ดู:
แม้ว่าข้อกำหนดจะทำให้ไลบรารี UUID ในเนมสเปซ std การใช้งานนี้ใช้ Namespace uuids เพื่อจุดประสงค์นี้เพื่อให้ห้องสมุดใช้งานได้โดยไม่ละเมิดข้อ จำกัด ที่กำหนดไว้ใน Namespace std มีประเภทและสาธารณูปโภคต่อไปนี้:
ประเภทพื้นฐาน:
| ชื่อ | คำอธิบาย |
|---|---|
uuid | ชั้นเรียนที่เป็นตัวแทนของ UUID; สิ่งนี้สามารถสร้างเริ่มต้นได้ (A NIL UUID) ที่สร้างขึ้นจากช่วง (กำหนดโดยคู่ของตัววนซ้ำ) หรือจาก span |
uuid_variant | พิมพ์ enum อย่างมากแสดงถึงประเภทของ UUID |
uuid_version | พิมพ์ enum อย่างมากซึ่งแสดงถึงเวอร์ชันของ UUID |
เครื่องกำเนิดไฟฟ้า:
| ชื่อ | คำอธิบาย |
|---|---|
basic_uuid_random_generator | วัตถุฟังก์ชั่นที่สร้าง UUID เวอร์ชัน 4 โดยใช้เครื่องกำเนิดเครื่องกำเนิดหมายเลขเทียม |
uuid_random_generator | A basic_uuid_random_generator โดยใช้เครื่องยนต์ Mersenne Twister ( basic_uuid_random_generator<std::mt19937> ) |
uuid_name_generator | วัตถุฟังก์ชั่นที่สร้าง UUIDs ที่ใช้ชื่อโดยใช้ SHA1 Hashing |
uuid_system_generator | วัตถุฟังก์ชั่นที่สร้าง UUIDs ใหม่โดยใช้ทรัพยากรระบบปฏิบัติการ ( CoCreateGuid บน Windows, uuid_generate บน Linux, CFUUIDCreate บน Mac)หมายเหตุ : นี่ไม่ใช่ส่วนหนึ่งของข้อเสนอมาตรฐาน จะใช้ได้เฉพาะในกรณีที่แมโคร UUID_SYSTEM_GENERATOR ถูกกำหนดไว้ |
uuid_time_generator | วัตถุฟังก์ชันการทดลองที่สร้าง UUID ตามเวลา หมายเหตุ : นี่เป็นคุณสมบัติการทดลองและไม่ควรใช้ในรหัสการผลิตใด ๆ จะใช้ได้เฉพาะเมื่อมีการกำหนด macro UUID_TIME_GENERATOR |
สาธารณูปโภค:
| ชื่อ | คำอธิบาย |
|---|---|
std::swap<> | ความเชี่ยวชาญเฉพาะของ swap สำหรับ uuid |
std::hash<> | ความเชี่ยวชาญของ hash สำหรับ uuid (จำเป็นสำหรับการจัดเก็บ uuids ในคอนเทนเนอร์ที่ไม่ได้เรียงลำดับเช่น std::unordered_set ) |
ค่าคงที่:
| ชื่อ | คำอธิบาย |
|---|---|
uuid_namespace_dns | NAMESPACE ID สำหรับ UUID ที่ใช้ชื่อเมื่อสตริงชื่อเป็นชื่อโดเมนที่ผ่านการรับรองอย่างสมบูรณ์ |
uuid_namespace_url | Namespace ID สำหรับ UUID ที่ใช้ชื่อเมื่อสตริงชื่อเป็น URL |
uuid_namespace_oid | NAMESPACE ID สำหรับ UUIDS ที่ใช้ชื่อเมื่อสตริง MAME เป็น ISO OID (ดู https://oidref.com/, https://en.wikipedia.org/wiki/object_identifier) |
uuid_namespace_x500 | NAMESPACE ID สำหรับ UUIDS ที่ใช้ชื่อเมื่อสตริงชื่อคือ X.500 DN ใน DER หรือรูปแบบเอาต์พุตข้อความ (ดู https://en.wikipedia.org/wiki/x.500, https://en.wikipedia.org/wiki/Abstract_Shet |
อื่น:
| ชื่อ | คำอธิบาย |
|---|---|
operator== และ operator!= | สำหรับการเปรียบเทียบ UUIDS เพื่อความเท่าเทียม/ความไม่เท่าเทียม |
operator< | สำหรับการเปรียบเทียบว่า UUIDs หนึ่งตัวนั้นน้อยกว่าอีกหรือไม่ แม้ว่าการดำเนินการนี้จะไม่สมเหตุสมผลมากนัก แต่ก็มีความจำเป็นในการจัดเก็บ UUID ใน STD :: Set |
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);การสร้าง UUID จากลำดับ 16 ไบต์
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");เปรียบเทียบ UUIDS
uuid empty;
uuid id = uuids::uuid_system_generator{}();
assert (empty == empty);
assert (id == id);
assert (empty != id);การแลกเปลี่ยน uuids
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)); หากคุณสร้าง UUIDS โดยใช้ basic_uuid_random_generator และ std :: random_device เพื่อเพาะพันธุ์เครื่องกำเนิดโปรดจำไว้ว่าสิ่งนี้อาจไม่ได้ไม่สามารถกำหนดได้และสร้างลำดับตัวเลขเดียวกัน:
STD :: Random_device อาจถูกนำไปใช้ในแง่ของเครื่องมือหมายเลขหลอกที่กำหนดโดยใช้งานหากแหล่งที่มาที่ไม่ได้กำหนด (เช่นอุปกรณ์ฮาร์ดแวร์) ไม่สามารถใช้งานได้ ในกรณีนี้วัตถุ STD :: Obland_Device แต่ละรายการอาจสร้างลำดับหมายเลขเดียวกัน
นี่อาจเป็นปัญหากับ Mingw ดูข้อผิดพลาด 85494 - การใช้งานของแบบสุ่มบน MingW นั้นไร้ประโยชน์ สิ่งนี้ได้รับการแก้ไขใน GCC 9.2
ทางเลือกแบบพกพาคือการใช้ห้องสมุด boost.random
ห้องสมุดได้รับการสนับสนุนในระบบปฏิบัติการที่สำคัญทั้งหมด: Windows, Linux และ Mac OS
หากคุณใช้ห้องสมุดในโครงการที่สร้างด้วย C ++ 20 คุณสามารถใช้ std::span สิ่งนี้ถูกใช้โดยค่าเริ่มต้นหากส่วนหัวได้รับการสนับสนุนโดยคอมไพเลอร์ของคุณ การตรวจสอบจะทำด้วยแมโครการทดสอบคุณสมบัติ __CPP_LIB_SPAN
มิฉะนั้นเช่นเมื่อสร้างด้วย C ++ 17, std::span ไม่สามารถใช้ได้ อย่างไรก็ตาม Microsoft Guidelines Support Library (AKA GSL) สามารถใช้สำหรับการใช้งาน span (ซึ่งกำหนดเวอร์ชันมาตรฐาน) ไลบรารี stduuid เริ่มต้นที่จะใช้การใช้งานนี้หากไม่สามารถใช้งานได้ std::span
เพื่อให้แน่ใจว่าสามารถใช้ gsl::span ได้ตรวจสอบให้แน่ใจว่ามีไลบรารี GSL และไดเรกทอรี GSL รวมอยู่ในรายการรวมของไดเรกทอรีสำหรับโครงการ
หากคุณใช้ CMAKE เพื่อสร้างโครงการทดสอบตรวจสอบให้แน่ใจว่าไม่มีการกำหนดตัวแปรที่เรียกว่า UUID_USING_CXX20_SPAN หรือค่าของมัน OFF (นี่คือค่าเริ่มต้น) สิ่งนี้จะช่วยให้มั่นใจได้ว่าไดเรกทอรี gsl จะรวมอยู่ในรายการค้นหาของไดเรกทอรีส่วนหัว
โครงการทดสอบมีอยู่ในแหล่งที่มา เพื่อสร้างและดำเนินการทดสอบทำดังต่อไปนี้:
build ในไดเรกทอรีรากของแหล่งที่มาcmake .. จากไดเรกทอรี build ; หากคุณไม่มี cmake คุณต้องติดตั้งก่อนตัวอย่าง
ในการสร้างไฟล์โครงการสำหรับ Visual Studio 2019 คุณสามารถเรียกใช้คำสั่งต่อไปนี้:
cd build
cmake -G "Visual Studio 17" -A x64 ..
ในการเปิดใช้งานระบบปฏิบัติการ UUID Generator ให้ตั้งค่าตัวแปร 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