A C ++ 17 تطبيق مكتبة منظمة CON-ONDORMERFORM للمعرفات الفريدة عالميًا ، ببساطة تعرف على UUID أو GUID (معظمها على Windows). UUID هو رقم 128 بت يستخدم لتحديد المعلومات الفريدة في أنظمة الكمبيوتر ، مثل مفاتيح جدول قاعدة البيانات ، وواجهات COM ، والفئات ، ومكتبات النوع ، وغيرها الكثير.
للحصول على معلومات حول Uuid/Guids انظر:
على الرغم من أن المواصفات تضع مكتبة UUID في مساحة اسم std ، فإن هذا التنفيذ يستخدم uuids الاسم لهذا الغرض ، من أجل جعل المكتبة قابلة للاستخدام دون انتهاك القيود المفروضة على مساحة اسم std . الأنواع والمرافق التالية متوفرة:
الأنواع الأساسية:
| اسم | وصف |
|---|---|
uuid | فئة تمثل uuid ؛ يمكن أن يتم إنشاء هذا افتراضيًا (nil uuid) ، تم إنشاؤه من نطاق (محدده زوج من المتكررين) ، أو من span . |
uuid_variant | نوع قوي من التعداد الذي يمثل نوع uuid |
uuid_version | من النوع بقوة تمثل إصدار UUID |
المولدات:
| اسم | وصف |
|---|---|
basic_uuid_random_generator | كائن دالة يقوم بإنشاء الإصدار 4 UUIDs باستخدام محرك مولد رقم العشوائي الزائف. |
uuid_random_generator | a basic_uuid_random_generator باستخدام محرك Mersenne Twister ( basic_uuid_random_generator<std::mt19937> ) |
uuid_name_generator | كائن وظيفة ينشئ الإصدار 5 ، UUIDs المستندة إلى الاسم باستخدام Hashing SHA1. |
uuid_system_generator | كائن دالة ينشئ UUIDs جديدة باستخدام موارد نظام التشغيل ( CoCreateGuid على Windows ، uuid_generate على Linux ، CFUUIDCreate على MAC)ملاحظة : هذا ليس جزءًا من الاقتراح القياسي. إنه متوفر فقط إذا تم تعريف Macro UUID_SYSTEM_GENERATOR . |
uuid_time_generator | كائن دالة تجريبية يولد UUIDs القائمة على الوقت. ملاحظة : هذه ميزة تجريبية ويجب عدم استخدامها في أي رمز إنتاج. إنه متوفر فقط إذا تم تعريف Macro UUID_TIME_GENERATOR . |
المرافق:
| اسم | وصف |
|---|---|
std::swap<> | تخصص swap لـ uuid |
std::hash<> | تخصص hash لـ uuid (ضروري لتخزين UUIDs في الحاويات الترابطية غير المرتبة ، مثل std::unordered_set ) |
الثوابت:
| اسم | وصف |
|---|---|
uuid_namespace_dns | معرف مساحة الاسم لـ UUIDs المستندة إلى الاسم عندما تكون سلسلة الاسم اسم مجال مؤهل بالكامل. |
uuid_namespace_url | معرف مساحة الاسم ل uuids المستندة إلى الاسم عندما تكون سلسلة الاسم عنوان URL. |
uuid_namespace_oid | معرف مساحة الاسم لـ UUIDs المستندة إلى الاسم عندما تكون سلسلة MAME عبارة عن ISO OID (انظر https://oidref.com/ ، https://en.wikipedia.org/wiki/Object_identifier). |
uuid_namespace_x500 | معرف مساحة الاسم ل uuids المستندة إلى الاسم عندما تكون سلسلة الاسم هي X.500 DN ، في DER أو تنسيق إخراج النص (انظر https://en.wikipedia.org/wiki/x.500 ، https://en.wikipedia.org/wiki/abstract_syntax_notation_on). |
آخر:
| اسم | وصف |
|---|---|
operator== operator!= | لمقارنة UUIDs للمساواة/عدم المساواة |
operator< | لمقارنة ما إذا كان uuids واحد أقل من الآخر. على الرغم من أن هذه العملية لا لها معنى منطقي كبير ، إلا أنها ضرورية من أجل تخزين uuids في مجموعة std ::. |
operator<< | لكتابة uuid إلى دفق الإخراج باستخدام التمثيل النصفي الكنسي. |
to_string() | ينشئ سلسلة مع التمثيل النصفي الكنسي لـ UUID. |
هذه المكتبة هي تطبيق للاقتراح P0959.
مع تطور الاقتراح بناءً على اللجنة القياسية وتعليقات المجتمع C ++ ، سيعكس تطبيق المكتبة هذه التغييرات.
انظر تاريخ المراجعة لاقتراح تاريخ التغييرات.
فيما يلي قائمة بالأمثلة لاستخدام المكتبة:
إنشاء لا شيء
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 :: random_device إنشاء تسلسل الرقم نفسه.
هذا يمكن أن يكون مشكلة مع Mingw. انظر Bug 85494 - تنفيذ Random_Device على MINGW غير مجدي. تم إصلاح هذا في GCC 9.2.
البديل المحمول هو استخدام مكتبة Boost.Random.
يتم دعم المكتبة على جميع أنظمة التشغيل الرئيسية: Windows و Linux و Mac OS.
إذا كنت تستخدم المكتبة في مشروع تم تصميمه باستخدام C ++ 20 ، فيمكنك استخدام std::span . يتم استخدام هذا افتراضيًا ، إذا كان الرأس مدعومًا من قبل المترجم الخاص بك. يتم الشيك باستخدام ماكرو اختبار الميزات __cpp_lib_span.
خلاف ذلك ، مثل البناء مع C ++ 17 ، std::span غير متوفر. ومع ذلك ، يمكن استخدام مكتبة دعم إرشادات Microsoft (المعروف أيضًا باسم 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 ..
لتمكين نظام التشغيل Generator UUID قم ON متغير UUID_SYSTEM_GENERATOR .
cd build
cmake -G "Visual Studio 17" -A x64 -DUUID_SYSTEM_GENERATOR=ON ..
لتمكين مولد UUID القائم على الوقت التجريبي ، قم ON متغير UUID_TIME_GENERATOR .
cd build
cmake -G "Visual Studio 17" -A x64 -DUUID_TIME_GENERATOR=ON ..
يعتمد تطبيق SHA1 على مكتبة Tinysha1.