شرح UUID: البنية ذات 128 بت والإصدارات وحالات الاستخدام الواقعية
في كل مرة تسجّل في خدمة، يُنشأ معرّف فريد لحسابك. كل طلب API يحمل معرّف تتبع. كل صف في قاعدة بيانات موزعة يحتاج مفتاحًا أساسيًا لن يتصادم مع مفاتيح مولّدة على أجهزة أخرى. الحل وراء كل هذا؟ UUID — معرّف فريد عالميًا.
يشرح هذا الدليل ما هي UUIDs، وكيف بُنيت، وما يفعله كل إصدار تحت الغطاء، ومتى تستخدمها (أو تتجنبها).
UUID بنظرة سريعة
UUID هو معرّف بحجم 128 بت (16 بايت) مصمم ليكون فريدًا عالميًا بدون الحاجة لسلطة مركزية. يُكتب كـ 32 رقمًا ست عشريًا بالتنسيق القياسي 8-4-4-4-12:
550e8400-e29b-41d4-a716-446655440000
|------| |--| |--| |--| |----------|
8 hex 4 4 4 12 hex
هذا 32 حرفًا ست عشريًا + 4 شرطات = 36 حرفًا إجمالًا. الشرطات تجميلية فقط — لا تحمل بيانات.
حقائق أساسية:
- 128 بت = 2¹²⁸ ≈ 3.4 × 10³⁸ قيمة ممكنة
- موحّد بمعيار RFC 9562 (مايو 2024، يحل محل RFC 4122)
- يُسمى أيضًا GUID (معرّف فريد عالميًا) في أنظمة Microsoft البيئية — نفس التنسيق، اسم مختلف
- مدعوم أصليًا من PostgreSQL (نوع
uuid)، وMySQL (BINARY(16)أوCHAR(36))، وتقريبًا كل لغة برمجة
تشريح UUID
كل UUID يرمّز حقلين من البيانات الوصفية في مواقع بت ثابتة، بغض النظر عن الإصدار:
550e8400-e29b-41d4-a716-446655440000
^ ^
| |
Version-┘ └-Variant
حقل الإصدار (البتات 48–51)
الرقم الست عشري الـ 13 (أول رقم من المجموعة الثالثة) يحدد إصدار UUID:
| الرقم الست عشري | الإصدار | الطريقة |
|---|---|---|
1 | v1 | طابع زمني + عنوان MAC |
3 | v3 | تجزئة MD5 لمساحة الاسم + الاسم |
4 | v4 | عشوائي تشفيريًا |
5 | v5 | تجزئة SHA-1 لمساحة الاسم + الاسم |
6 | v6 | طابع زمني مُعاد ترتيبه (RFC 9562) |
7 | v7 | طابع Unix الزمني + عشوائي (RFC 9562) |
8 | v8 | مخصص / خاص بالتطبيق |
حقل المتغير (البتات 64–65)
الرقم الست عشري الـ 17 (أول رقم من المجموعة الرابعة) يحدد المتغير. لمعرّفات RFC 4122/9562، البتات الأولى هي 10، مما يعني أن هذا الرقم دائمًا 8 أو 9 أو a أو b.
مثال تفصيلي
550e8400-e29b-41d4-a716-446655440000
↑ ↑
4 → v4 a → RFC 4122 variant
This is a UUID v4 (random), RFC 4122/9562 variant.
شرح إصدارات UUID
الإصدار 1: طابع زمني + عنوان MAC
كان UUID v1 التصميم الأصلي. يرمّز:
- طابع زمني 60 بت — فترات 100 نانوثانية منذ 15 أكتوبر 1582 (إصلاح التقويم الغريغوري)
- تسلسل ساعة 14 بت — عداد رتابة لمنع التكرار عند عودة الساعة
- عقدة 48 بت — عادة عنوان MAC للجهاز
| Timestamp | Ver | Clk |Var| Node (MAC) |
| 60 bits | 4b | 14b |2b | 48 bits |
المشاكل:
- يكشف وقت التوليد وهوية الجهاز (مخاطر خصوصية)
- يمكن انتحال عناوين MAC، مما يقوّض الفرادة
- حقبة 1582 محيرة وتتطلب تحويلًا
الحكم: أُهمل بواسطة RFC 9562. استخدم v7 بدلًا من ذلك للمعرّفات المبنية على الوقت.
الإصدار 3: مبني على الاسم بـ MD5 (حتمي)
يجزّئ UUID v3 معرّف مساحة اسم UUID وسلسلة نصية باستخدام MD5. نفس المدخلات تنتج دائمًا نفس UUID.
import uuid
# namespace = DNS, name = "example.com"
print(uuid.uuid3(uuid.NAMESPACE_DNS, "example.com"))
# → "9073926b-929f-31c2-abc9-fad77ae3e8eb" (always this value)
أربع مساحات أسماء قياسية معرّفة:
- DNS:
6ba7b810-9dad-11d1-80b4-00c04fd430c8 - URL:
6ba7b811-9dad-11d1-80b4-00c04fd430c8 - OID:
6ba7b812-9dad-11d1-80b4-00c04fd430c8 - X.500:
6ba7b814-9dad-11d1-80b4-00c04fd430c8
الحكم: وظيفي لكن فضّل v5 — SHA-1 أقوى من MD5.
الإصدار 4: عشوائي — الأكثر شعبية
يملأ UUID v4 122 بت ببيانات عشوائية مشفرة تشفيريًا (البتات الـ 6 المتبقية محجوزة لحقلي الإصدار والمتغير).
| Random | Ver | Random |Var| Random |
| 48 bits | 4b | 12 bits |2b | 62 bits |
مع 2¹²² ≈ 5.3 × 10³⁶ قيمة ممكنة، احتمال التصادم منخفض فلكيًا. للوصول إلى فرصة 50% لتصادم واحد على الأقل، ستحتاج حوالي 2.71 × 10¹⁸ UUID — أي 2.71 كوينتيليون.
// Every modern browser and Node.js supports this
const id = crypto.randomUUID();
console.log(id); // → "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
نقاط القوة: بسيط، خاص، مدعوم عالميًا، لا حاجة لتنسيق.
نقطة الضعف: التوزيع العشوائي يسبب تجزئة فهرس B-tree عند استخدامه كمفاتيح أساسية لقواعد البيانات. لحالات الاستخدام كثيفة قواعد البيانات، فكّر في v7.
الإصدار 5: مبني على الاسم بـ SHA-1 (حتمي)
مطابق لـ v3 لكن يستخدم SHA-1 بدلًا من MD5. نفس المدخلات تنتج دائمًا نفس UUID.
import uuid
print(uuid.uuid5(uuid.NAMESPACE_DNS, "example.com"))
# → "cfbff0d1-9375-5685-968c-48ce8b15ae17" (always this value)
حالات الاستخدام:
- توليد معرّفات مستقرة من عناوين URL أو أسماء DNS
- مفاتيح تخزين معنونة بالمحتوى
- بيانات اختبار قابلة للتكرار
مهم: v3 وv5 ليسا مخصصين للأمان. هما حتميان — أي شخص يعرف مساحة الاسم والاسم يمكنه إعادة إنتاج UUID.
الإصدار 7: طابع Unix الزمني + عشوائي (موصى به للمشاريع الجديدة)
UUID v7 هو أحدث إصدار، قُدّم في RFC 9562 (مايو 2024). يرمّز:
- طابع Unix زمني 48 بت بالملي ثانية — متزايد رتيبًا
- 74 بت من العشوائية التشفيرية
| Unix timestamp (ms) | Ver | rand_a |Var| rand_b |
| 48 bits | 4b | 12 bits |2b | 62 bits |
هذا يعني أن معرّفات v7 مرتبة طبيعيًا حسب وقت الإنشاء — المعرّفات الأحدث دائمًا أكبر معجميًا من الأقدم. هذه الخاصية تجعلها مثالية لمفاتيح قواعد البيانات الأساسية، حيث تبقى فهارس B-tree تسلسلية بدلًا من التجزئة العشوائية.
import { v7 as uuidv7 } from "uuid";
const id1 = uuidv7(); // generated at T₁
const id2 = uuidv7(); // generated at T₂ (T₂ > T₁)
console.log(id1 < id2); // → true (lexicographic comparison)
لماذا هذا مهم لقواعد البيانات: خاصية التسلسل في v7 تقلل انقسامات صفحات الفهرس بنسبة تصل إلى 90% مقارنة بـ v4، مما ينتج إدراجات أسرع وفهارس أصغر وأداء ذاكرة تخزين مؤقت أفضل.
UUID مقابل GUID — ما الفرق؟
لا يوجد فرق وظيفي. GUID (معرّف فريد عالميًا) هو اسم Microsoft لـ UUID، يُستخدم في Windows و.NET وCOM وSQL Server. التنسيق متطابق: 128 بت، 8-4-4-4-12 ست عشري.
الفرق التجميلي الوحيد: أدوات Microsoft تعرض أحيانًا GUIDs بـ أحرف كبيرة مع أقواس معقوفة:
UUID: 550e8400-e29b-41d4-a716-446655440000
GUID: {550E8400-E29B-41D4-A716-446655440000}
إذا سأل أحد عن “الفرق بين UUID وGUID”، الجواب هو: العلامة التجارية.
قيم UUID الخاصة
يعرّف RFC 9562 معرّفين خاصين:
| الاسم | القيمة | الغرض |
|---|---|---|
| Nil UUID | 00000000-0000-0000-0000-000000000000 | يمثل غياب القيمة (مثل null) |
| Max UUID | ffffffff-ffff-ffff-ffff-ffffffffffff | علامة حدود أو قيمة حارسة |
لا تستخدم هذين كمعرّفات فعلية أبدًا — فهما ليسا فريدين بحكم التعريف.
احتمالية التصادم: مسألة عيد الميلاد
تحسب “مسألة عيد الميلاد” كم UUID تحتاج قبل أن يصبح التصادم محتملًا. لـ UUID v4 (122 بت عشوائية):
| UUIDs المولّدة | احتمالية التصادم |
|---|---|
| مليون | ~10⁻²² (مستحيل عمليًا) |
| مليار | ~10⁻¹⁶ (لا يزال مهملًا) |
| 2.71 × 10¹⁸ | 50% (حد “عيد الميلاد”) |
لوضع الأمور في السياق: إذا ولّدت مليار UUID في الثانية، سيستغرق الأمر 86 سنة للوصول إلى فرصة 50% لتصادم واحد. عمليًا، فشل الأجهزة وأخطاء البرمجيات والأشعة الكونية كلها أكثر احتمالًا لإنتاج تكرار من رياضيات UUID v4.
الصيغة: p(n) ≈ n² / (2 × 2¹²²)
كيفية التحقق من صحة UUID
UUID صالح يطابق نمط التعبير النمطي هذا (غير حساس لحالة الأحرف):
^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
هذا يتحقق من:
- تنسيق 8-4-4-4-12 الست عشري
- رقم الإصدار 1–7 (الموقع 15)
- نصف بايت المتغير يبدأ بـ 8 أو 9 أو a أو b (الموقع 20)
function isValidUUID(str) {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str);
}
isValidUUID("550e8400-e29b-41d4-a716-446655440000"); // → true
isValidUUID("not-a-uuid"); // → false
توليد UUIDs في كل لغة
JavaScript / TypeScript
// Browser & Node.js — built-in v4
crypto.randomUUID();
// npm uuid package — supports v1, v3, v4, v5, v7
import { v4, v7 } from "uuid";
v4(); // random
v7(); // time-ordered
Python
import uuid
uuid.uuid4() # random
uuid.uuid5(uuid.NAMESPACE_DNS, "example.com") # deterministic
# uuid.uuid7() planned for Python 3.14+
Go
import "github.com/google/uuid"
uuid.New() // v4 random
uuid.Must(uuid.NewV7()) // v7 time-ordered
Java
import java.util.UUID;
UUID.randomUUID(); // v4 random
// UUID v7: use com.fasterxml.uuid or java.util.UUID in JDK 21+
SQL (PostgreSQL)
-- v4 (PostgreSQL 13+)
SELECT gen_random_uuid();
-- v7 (PostgreSQL 18+)
SELECT uuidv7();
حالات الاستخدام الشائعة
مفاتيح قواعد البيانات الأساسية
تتيح لك UUIDs توليد المعرّفات في أي مكان — في التطبيق، على العميل، على الحافة — بدون رحلة ذهاب وإياب لقاعدة البيانات. هذا يمكّن بنيات العمل بدون اتصال أولًا ويبسّط الأنظمة الموزعة. استخدم v7 لأفضل أداء فهرسة، أو v4 إذا لم تهتم بالترتيب.
تتبع طلبات API
عيّن UUID لكل طلب API عند نقطة الدخول (البوابة، موازن الحمل). مرّره عبر جميع الخدمات التالية في ترويسة مثل X-Request-ID. هذا يجعل ربط السجلات عبر الخدمات المصغرة أمرًا بسيطًا.
مفاتيح التمكين
تستخدم واجهات API معرّفات UUID كمفاتيح تمكين لضمان أن الطلبات المعادة لا تنشئ موارد مكررة. يولّد العميل UUID قبل المحاولة الأولى ويرسل نفس UUID في المحاولات المعادة.
معرّفات الجلسات
توفر UUIDs فرادة كافية لمنع تصادمات الجلسات عبر قواعد مستخدمين كبيرة. بخلاف الأعداد الصحيحة التلقائية التزايد، لا يمكن تعدادها — لا يستطيع المهاجم تخمين معرّفات جلسات صالحة بزيادة رقم.
التخزين المعنون بالمحتوى
يولّد UUID v5 معرّفات حتمية من المحتوى. بنفس المدخل، تحصل دائمًا على نفس UUID — مفيد لإزالة التكرار والتخزين المؤقت والبناء القابل للتكرار.
اعتبارات الأمان
UUIDs ليست رموز أمان
صُممت UUIDs لـ الفرادة، وليس السرية. مشاكل أساسية:
- UUID v1 يكشف الطابع الزمني للتوليد وعنوان MAC
- UUID v4 يمتلك 122 بت عشوائية لكن ببنية متوقعة (بتات الإصدار/المتغير ثابتة)
- UUID v3/v5 حتميان — أي شخص يعرف مساحة الاسم والاسم يمكنه إعادة إنتاج UUID
لرموز الأمان ومفاتيح API وأسرار الجلسات، استخدم مولّد أرقام عشوائية تشفيرية مخصصًا بـ 128+ بت من العشوائية البحتة:
// For security tokens — NOT a UUID, but fully random
const token = Array.from(crypto.getRandomValues(new Uint8Array(32)))
.map(b => b.toString(16).padStart(2, "0"))
.join("");
UUID v7 يكشف وقت الإنشاء
أول 48 بت من UUID v7 ترمّز الطابع الزمني للإنشاء بالملي ثانية. أي شخص يستقبل UUID v7 يمكنه استخراج وقت إنشائه:
const hex = "01906b5e-4a3e-7234-8f56-b8c12d4e5678".replace(/-/g, "").slice(0, 12);
new Date(parseInt(hex, 16));
// → 2024-07-01T12:34:56.000Z
إذا كان وقت الإنشاء معلومة حساسة، استخدم v4 بدلًا من ذلك.
لا تستخدم UUIDs لمنع التعداد
بينما UUIDs أصعب في التخمين من الأعداد الصحيحة التسلسلية، يجب ألا تكون آلية التحكم في الوصول الوحيدة لديك. فرض دائمًا فحوصات التفويض — لا تعتمد على غموض عناوين URL.
الأسئلة الشائعة
لماذا توجد شرطات في UUIDs؟
الشرطات في تنسيق 8-4-4-4-12 تجميلية بحتة لتسهيل القراءة البشرية. لا تحمل بيانات ويتم تجاهلها أثناء التحليل. بعض الأنظمة تخزّن UUIDs بدون شرطات (32 حرفًا ست عشريًا)، وهو صالح أيضًا.
هل يمكن أن يتطابق UUID-ان؟
نظريًا نعم، عمليًا لا. لـ UUID v4 بـ 122 بت عشوائية، احتمالية توليد UUID-ين متطابقين هي حوالي 1 من 5.3 × 10³⁶ لأي زوج معطى. بمعدلات التوليد الواقعية، من المرجح أن تُضرب بالبرق أثناء فوزك باليانصيب أكثر من مصادفة تصادم UUID.
هل UUIDs تسلسلية؟
بعض الإصدارات فقط. UUID v1 وv6 وv7 تحتوي طوابع زمنية وتُرتّب زمنيًا. UUID v4 عشوائي بالكامل بدون ترتيب. UUID v3 وv5 حتميان لكن غير مرتبين.
كم مساحة تخزين يستهلكها UUID؟
- ثنائي: 16 بايت (128 بت) — التخزين الأكثر كفاءة
- سلسلة نصية (مع شرطات): 36 بايت (ASCII)
- سلسلة نصية (بدون شرطات): 32 بايت (ASCII)
معظم قواعد البيانات تخزّن UUIDs بالتنسيق الثنائي داخليًا. نوع uuid الأصلي في PostgreSQL يستخدم بالضبط 16 بايت.
هل أستخدم UUID أم التزايد التلقائي للمفاتيح الأساسية؟
التزايد التلقائي أبسط لتطبيقات قاعدة البيانات الواحدة (أصغر، أسرع، تسلسلي). UUID أفضل للأنظمة الموزعة (ولّد في أي مكان، بدون تنسيق، آمن للدمج). إذا استخدمت UUID، فضّل v7 لأفضل أداء قاعدة بيانات.
ما هو RFC 9562؟
RFC 9562، المنشور في مايو 2024، هو أحدث معيار UUID. يحل محل RFC 4122 ويقدم رسميًا إصدارات UUID 6 و7 و8. يُهمل v1 لصالح v6/v7 ويعرّف قيمتي UUID الخاصتين nil وmax. إذا كنت تنفّذ توليد أو التحقق من UUID، فـ RFC 9562 هو المرجع الرسمي.
هل يمكنني استخدام UUIDs عبر لغات برمجة مختلفة؟
نعم. تنسيق UUID (128 بت، 8-4-4-4-12 ست عشري) مستقل عن اللغة. UUID مولّد في JavaScript سيُحلّل بشكل صحيح في Python وGo وJava أو أي لغة أخرى تدعم UUID. هذا التوافق المتبادل أحد أعظم نقاط قوة UUID.
ولّد وفكّك وتحقق من UUIDs فوريًا مع مولّد UUID — يدعم v1 وv4 وv5 وv7 مع التوليد بالجملة، 100% في متصفحك.
تختار بين إصدارات UUID لمشروعك القادم؟ اقرأ مقارنة UUID v4 مقابل v7 مقابل ULID مقابل Snowflake لدليل اختيار عملي مع اختبارات أداء قواعد البيانات وأمثلة برمجية.