مولّد UUID v3
يولد UUID v3 حتمية مبنية على الاسم باستخدام MD5
فضاء الأسماء
6ba7b810-9dad-11d1-80b4-00c04fd430c8
الاسم
UUID v3 المولّد
ما هو UUID v3؟
UUID v3 هو إصدار UUID مبني على الأسماء معرَّف في RFC 4122. بدلاً من بيانات عشوائية أو طابع زمني، يشتق UUID حتمياً من مدخلين: UUID فضاء أسماء وسلسلة اسم. يُجزَّأ زوج الفضاء المسمّى + الاسم باستخدام MD5، ويُنسَّق التجزيء الناتج كـ UUID.
الخاصية الرئيسية لـ UUID v3 هي الحتمية: نفس الفضاء المسمّى والاسم سينتجان دائماً UUID مطابقاً، على أي جهاز، في أي وقت. هذا يجعله مناسباً لعنونة المحتوى — توليد معرّفات ثابتة للموارد المحدَّدة باسم ذي معنى.
يستخدم UUID v3 MD5 كدالة تجزئة. يُعتبَر MD5 محطوماً تشفيرياً لأغراض الأمان، وهذا هو سبب تفضيل UUID v5 (الذي يستخدم SHA-1) عموماً للتطوير الجديد. لا يوفّر v3 ولا v5 أي عشوائية — إنهما حتميان بالكامل.
الفضاءات المسمّاة القياسية
يعرّف RFC 4122 أربعة UUID لفضاء أسماء مخصَّصة مسبقاً. استخدام فضاء أسماء قياسي يضمن قابلية التشغيل البيني — سيولّد تطبيقان مستقلان UUID v3 ذاته لنفس الاسم ضمن نفس الفضاء المسمّى:
| الفضاء المسمّى | UUID | استخدم لـ |
|---|---|---|
| DNS | 6ba7b810-9dad-11d1-80b4-00c04fd430c8 | أسماء نطاقات مؤهَّلة بالكامل (مثلاً 'example.com') |
| URL | 6ba7b811-9dad-11d1-80b4-00c04fd430c8 | عناوين URL وURIs (مثلاً 'https://example.com/resource') |
| OID | 6ba7b812-9dad-11d1-80b4-00c04fd430c8 | معرّفات كائن ISO (مثلاً '1.2.840.113556') |
| X.500 | 6ba7b814-9dad-11d1-80b4-00c04fd430c8 | أسماء مميَّزة X.500 (مثلاً 'cn=John,dc=example,dc=com') |
يمكنك أيضاً استخدام أي UUID تعسّفي كفضاء أسماء مخصَّص — مثلاً UUID v4 تولّده مرة واحدة وتضمّنه في تطبيقك كثابت. يتيح لك هذا إنشاء فضاء أسماء خاص لتعيينات الاسم-إلى-UUID الخاصة بك.
UUID v3 مقابل UUID v5
UUID v3 وUUID v5 متطابقان بنيوياً — كلاهما UUID حتمية مبنية على الأسماء. الفرق الوحيد هو دالة التجزئة:
- يستخدم تجزئة MD5
- ناتج 128 بت (بحجم UUID)
- معرَّف في RFC 4122
- MD5 محطوم تشفيرياً
- مدعوم من جميع مكتبات UUID
- يستخدم تجزئة SHA-1
- تجزيء 160 بت مبتور إلى 128 بت
- معرَّف في RFC 4122
- SHA-1 مهجور للاستخدام الأمني لكنه أقوى من MD5
- مدعوم من جميع مكتبات UUID
يُفضَّل UUID v5 على UUID v3 لجميع التطوير الجديد. تجزيء SHA-1 أقوى من MD5 والفرق في الأداء ضئيل. استخدم UUID v3 فقط حين تحتاج إعادة إنتاج UUID من نظام يستخدمه بالفعل.
متى تستخدم UUID v3
UUID v3 (وv5) مناسبان حين تحتاج إلى معرّف ثابت قابل للاستنساخ مشتق من اسم ذي معنى — بدلاً من معرّف عشوائي يجب تخزينه والبحث عنه:
فهم الحتمية
حتمية UUID v3 هي أعظم قوّته وأهم قيوده في آنٍ واحد. بالنظر إلى أي UUID فضاء أسماء وأي سلسلة اسم، يكون UUID الناتج ثابتاً كلياً — لا عشوائية فيه. هذا يعني:
ينتج دائماً: 9073926b-929f-31c2-abc9-fad77ae3e8eb
إذا عرف المهاجم الفضاء المسمّى واستطاع تخمين الاسم، يستطيع حساب UUID v3 مسبقاً. لا ينبغي أبداً استخدام قيم UUID v3 كرموز غير قابلة للتنبؤ أو معرّفات جلسة أو أسرار. استخدم UUID v4 لأي معرّف حساس أمنياً.
أمثلة الكود
يتطلب UUID v3 UUID فضاء أسماء وسلسلة اسم. استخدم حزمة uuid القياسية:
// Browser / Node.js — UUID v3 without dependencies
function uuidV3(namespace, name) {
// namespace must be a UUID string like '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
const nsBytes = namespace.replace(/-/g, '').match(/../g).map(h => parseInt(h, 16))
const nameBytes = [...new TextEncoder().encode(name)]
const combined = new Uint8Array([...nsBytes, ...nameBytes])
// md5(combined) — use your preferred MD5 library or the inline implementation
const hash = md5(combined) // returns Uint8Array(16)
hash[6] = (hash[6] & 0x0f) | 0x30 // version 3
hash[8] = (hash[8] & 0x3f) | 0x80 // variant
const h = [...hash].map(b => b.toString(16).padStart(2, '0')).join('')
return `${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20)}`
}
// Using the 'uuid' npm package
import { v3 as uuidv3 } from 'uuid'
const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
console.log(uuidv3('example.com', uuidv3.DNS))
// → '9073926b-929f-31c2-abc9-fad77ae3e8eb' (always the same)import uuid
# Using the standard library
dns_uuid = uuid.uuid3(uuid.NAMESPACE_DNS, 'example.com')
print(dns_uuid)
# → 9073926b-929f-31c2-abc9-fad77ae3e8eb
url_uuid = uuid.uuid3(uuid.NAMESPACE_URL, 'https://example.com/page')
print(url_uuid)
# Custom namespace
MY_NS = uuid.UUID('a1b2c3d4-e5f6-7890-abcd-ef1234567890')
custom = uuid.uuid3(MY_NS, 'my-entity-name')
print(custom)package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
// Standard DNS namespace
ns := uuid.MustParse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
id := uuid.NewMD5(ns, []byte("example.com"))
fmt.Println(id)
// → 9073926b-929f-31c2-abc9-fad77ae3e8eb
// URL namespace
urlNS := uuid.MustParse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
idURL := uuid.NewMD5(urlNS, []byte("https://example.com/page"))
fmt.Println(idURL)
}