تولیدکننده UUID v4
تولید UUID v4 رمزنگاریشده تصادفی
…
فرمتبندی
UUID v4 پرکاربردترین نسخه UUID در نرمافزارهای مدرن است. برخلاف نسخههای دیگر که بیتها را از یک timestamp یا هش namespace استخراج میکنند، UUID v4 کاملاً از دادههای تصادفی ساخته میشود — که آن را سادهترین و قابلحملترین گزینه میکند هر زمان که به یک شناسه یکتا نیاز دارید که هیچ متادیتایی درباره منشأ خود ندارد.
این مولد از crypto.randomUUID() استفاده میکند، API بومی مرورگر و Node.js، که آنتروپی را از مولد اعداد تصادفی امن رمزنگاریشده سیستمعامل — همان منبعی که برای کلیدهای TLS استفاده میشود — دریافت میکند.
UUID v4 چیست؟
شناسه یکتای جهانی (UUID) یک برچسب ۱۲۸ بیتی است که در RFC 4122 استانداردسازی شده. معمولاً به صورت ۳۲ رقم هگزادسیمال که با خط تیره در الگوی 8-4-4-4-12 گروهبندی شدهاند نمایش داده میشود:
در UUID v4، ۱۲۲ از ۱۲۸ بیت تصادفی هستند. ۶ بیت باقیمانده فیلدهای ثابتی هستند که توسط مشخصات تعریف شدهاند: ۴ بیت نسخه را رمزگذاری میکنند (0100 = 4) و ۲ بیت گونه RFC 4122 را (10). همین بیتهای ثابت هستند که باعث میشوند گروه سوم همیشه با 4 شروع شود و گروه چهارم همیشه با 8، 9، a یا b آغاز شود.
ساختار یک UUID v4
تجزیه 550e8400-e29b-41d4-a716-446655440000:
| بخش | بیتها | معنا |
|---|---|---|
| 550e8400 | ۳۲ تصادفی | time_low (نام تاریخی — در v4 کاملاً تصادفی است) |
| e29b | ۱۶ تصادفی | time_mid (نام تاریخی — در v4 کاملاً تصادفی است) |
| 41d4 | ۴ ثابت + ۱۲ تصادفی | نیبل نسخه 4 (باینری 0100) + ۱۲ بیت تصادفی |
| a716 | ۲ ثابت + ۱۴ تصادفی | بیتهای گونه 10 (MSBهای اولین بایت) + ۱۴ بیت تصادفی |
| 446655440000 | ۴۸ تصادفی | node (در v4 کاملاً تصادفی است) |
8، 9، a یا b است — زیرا دو بیت بالایی آن بایت به 10 (نشانگر گونه RFC 4122) ثابت شدهاند و دو بیت باقیمانده آزاد هستند.UUID v4 در برابر نسخههای دیگر
RFC 4122 پنج نسخه UUID تعریف میکند. هر کدام مشکل متفاوتی را حل میکنند:
یک timestamp 60 بیتی (بازههای 100 نانوثانیهای از اکتبر ۱۵۸۲) را با آدرس MAC دستگاه ترکیب میکند. در یک دستگاه به صورت یکنواخت افزایشی است.
Use when: به IDهای مرتبشده زمانی نیاز دارید و مشکلی با افشای هویت سرور و زمان تولید ندارید.
قطعی: یک namespace + نام یکسان همیشه UUID یکسانی تولید میکند. از هشسازی MD5 استفاده میکند.
Use when: به IDهای قابل تکرار از یک namespace شناختهشده نیاز دارید (مثلاً نامهای DNS). v5 را به v3 ترجیح دهید.
۱۲۲ بیت تصادفی امن رمزنگاریشده. بدون timestamp، بدون MAC، بدون namespace. رایجترین انتخاب همهمنظوره.
Use when: به IDهای یکتا بدون معنای ساختاری و با حداکثر حریم خصوصی نیاز دارید.
مانند v3 اما از SHA-1 استفاده میکند. همچنان از namespace + نام قطعی است.
Use when: به شناسههای قابل تکرار و آدرسدهیشده بر اساس محتوا نیاز دارید (مثلاً IDهای پایدار برای منابع شناساییشده با URL).
جدیدتر (RFC 9562، ۲۰۲۴). یک timestamp میلیثانیهای Unix را در بیتهای بالایی رمزگذاری میکند، سپس بیتهای تصادفی. قابل مرتبسازی و مناسب پایگاه داده.
Use when: به IDهای مناسب ایندکس پایگاه داده با ترتیب زمانی طبیعی نیاز دارید (برای پروژههای جدید به جای v1 ترجیح دهید).
چه زمانی از UUID v4 استفاده کنیم
UUID v4 در اکثر موقعیتهایی که به سادگی به «یک ID یکتا» بدون محدودیت اضافی نیاز دارید، ابزار مناسبی است:
IDهای کاربر و حساب
IDهای کاربر مبهم که هیچ اطلاعاتی درباره زمان ایجاد حساب یا هویت سرور فاش نمیکنند. قابل شمارش یا حدسزدن نیستند.
کلیدهای اصلی پایگاه داده
با هر موتور پایگاه دادهای کار میکند. تولید UUID v4 در سمت کلاینت و ادغام از منابع توزیعشده بدون هماهنگی امن است — نیازی به جدول دنباله یا سرویس مرکزی ID نیست.
IDهای نشست و توکن
۱۲۲ بیت تصادفی، حدسزدن brute-force را از نظر محاسباتی غیرممکن میکند — قدرتی برابر با یک توکن تصادفی ۱۲۲ بیتی.
نامهای فایل و شیء
نام فایلهای مقاوم در برابر تکراری شدن برای آپلودها، کلیدهای شیء S3 یا ورودیهای کش. خطری از نوشتن دو کلاینت روی یک کلید یکسان وجود ندارد.
کلیدهای idempotency
قبل از ارسال یک درخواست، یک UUID در کلاینت تولید کنید. سرور میتواند بهطور ایمن درخواستهای تکراری شده را بدون یک شمارنده مشترک حذف تکراری کند.
IDهای همبستگی و trace
یک UUID را به هر خط لاگ و span trace توزیعشده متصل کنید. نیازی به هماهنگی در سرویسها یا دستگاههای مختلف نیست.
احتمال تصادم
با ۱۲۲ بیت تصادفی، فضای UUID v4 شامل 2122 ≈ 5.3 × 1036 مقدار ممکن است. احتمال تصادم از مسئله تولد پیروی میکند:
معیار رایج اشارهشده: برای داشتن ۵۰٪ شانس یک تصادم واحد، باید تقریباً 2.71 × 1018 UUID تولید کنید. با نرخ ۱ میلیارد UUID در ثانیه، این کار تقریباً ۸۵ سال تولید پیوسته طول میکشد. برای هر برنامه دنیای واقعی، تصادم نگرانی عملی نیست.
مثالهای کد
JavaScript — مرورگر و Node.js 14.17+
متد crypto.randomUUID() به صورت بومی در تمام مرورگرهای مدرن (Chrome 92+، Firefox 95+، Safari 15.4+) و در Node.js 14.17+ موجود است. نیازی به نصب پکیج نیست.
// Browser or Node.js 14.17+
const id = crypto.randomUUID()
// → "110e8400-e29b-41d4-a716-446655440000"
// Generate multiple
const ids = Array.from({ length: 5 }, () => crypto.randomUUID())Node.js — نسخههای قدیمیتر (پکیج uuid)
const { v4: uuidv4 } = require('uuid')
const id = uuidv4()
// → "110e8400-e29b-41d4-a716-446655440000"Python
import uuid # Generate a UUID v4 id = str(uuid.uuid4()) # → '110e8400-e29b-41d4-a716-446655440000' # The uuid module uses os.urandom() — cryptographically secure print(uuid.uuid4().hex) # without hyphens # → '110e8400e29b41d4a716446655440000'
Go
import "github.com/google/uuid" id := uuid.New().String() // → "110e8400-e29b-41d4-a716-446655440000" // Or using the standard library (Go 1.20+ with math/rand/v2 is NOT cryptographic) // Always prefer github.com/google/uuid for production use
Rust
# Cargo.toml
[dependencies]
uuid = { version = "1", features = ["v4"] }use uuid::Uuid; let id = Uuid::new_v4().to_string(); // → "110e8400-e29b-41d4-a716-446655440000"
سوالات متداول
آیا UUID v4 از نظر رمزنگاری امن است؟
UUID v4 خودش یک اصل امنیتی نیست — یک فرمت شناسه است. اما وقتی از طریق crypto.randomUUID() (مرورگر یا Node.js) یا APIهای معادل در سطح سیستمعامل تولید میشود، آنتروپی پایه از نظر رمزنگاری امن است. این به این معنی است که مقادیر UUID v4 برای استفاده به عنوان توکنهای نشست یا کلیدهای idempotency مناسب هستند، جایی که غیرقابل پیشبینی بودن اهمیت دارد. از مولدهای UUID مبتنی بر Math.random() برای زمینههای حساس به امنیت استفاده نکنید — فقط از APIهایی استفاده کنید که صریحاً از CSPRNG سیستمعامل استفاده میکنند.
آیا دو UUID v4 میتوانند برابر باشند؟
از نظر نظری بله، اما در عمل خیر. احتمال تولید یک تکراری در هر مجموعه داده واقعی (میلیاردها ID) بسیار ناچیز است — بسیار کمتر از احتمال خرابی سختافزاری که باعث خراب شدن داده شود. تصادم UUID v4 در طراحی سیستم تولیدی غیرممکن فرض میشود. اگر واقعاً به تضمین عدم تصادم نیاز دارید، به جای آن از یک شمارنده مرکزی یا یک دنباله پایگاه داده استفاده کنید.
UUID v4 در برابر nanoid — کدام را باید استفاده کنم؟
هر دو مولد ID تصادفی با پشتیبانی CSPRNG هستند. تفاوتهای کلیدی:
- UUID v4 از استاندارد RFC 4122 پیروی میکند، توسط هر پایگاه داده و فریمورکی شناخته میشود و نیاز به هیچ وابستگیای ندارد (بومی
crypto.randomUUID()). - nanoid از یک الفبای URL-safe استفاده میکند و به صورت پیشفرض کوتاهتر است (۲۱ کاراکتر در مقابل ۳۶). وقتی طول URL یا خوانایی اهمیت دارد مفید است. نیاز به یک پکیج npm دارد.
وقتی قابلیت همکاری با سیستمهای خارجی اهمیت دارد (APIها، پایگاههای داده، زیرساخت لاگینگ)، UUID v4 را ترجیح دهید. وقتی IDهای کوتاهتر میخواهید و کل پشته را کنترل میکنید، nanoid را ترجیح دهید.
آیا باید UUIDها را به صورت رشته یا باینری در پایگاه داده ذخیره کنم؟
برای اکثر پایگاههای داده، ذخیره به عنوان ستون UUID یا BINARY(16) (۱۶ بایت) کارآمدتر از یک رشته VARCHAR(36) (۳۶ بایت) است. PostgreSQL یک نوع uuid بومی دارد. MySQL و MariaDB با BINARY(16) و کمککنندههای UUID_TO_BIN() / BIN_TO_UUID() به خوبی کار میکنند. کاربران SQLite معمولاً به صورت TEXT ذخیره میکنند. انتخاب ذخیرهسازی هیچ تأثیری بر یکتایی یا درستی ندارد.
چرا UUID v4 خط تیره دارد — و آیا میتوانم آنها را حذف کنم؟
خطهای تیره بخشی از نمایش کانونیکال UUID هستند که توسط RFC 4122 تعریف شده. آنها صرفاً زیبایی هستند — هیچ اطلاعاتی حمل نمیکنند و بر مقدار ۱۲۸ بیتی تأثیر نمیگذارند. حذف آنها به شما یک رشته هگز فشرده ۳۲ کاراکتری میدهد که از نظر عملکردی معادل است. اکثر پارسرهای UUID هر دو فرم را میپذیرند. در صورت شک، از فرم کانونیکال با خط تیره برای حداکثر سازگاری با ابزارها و پایگاههای داده شخص ثالث استفاده کنید.
const id = crypto.randomUUID() // "550e8400-e29b-41d4-a716-446655440000"
const compact = id.replaceAll('-', '') // "550e8400e29b41d4a716446655440000"