CUID2 Üretici
Güvenli yeni nesil CUID2 tanımlayıcıları oluşturur
Oluşturulan CUID2'ler
CUID2 Nedir?
CUID2 (Çarpışmaya Dayanıklı Benzersiz Kimlik, sürüm 2), veritabanlarında, URL'lerde ve dağıtılmış sistemlerde birincil anahtar olarak güvenle kullanılabilen kısa, kriptografik olarak güvenli ve opak kimlikler oluşturmak için tasarlanmış CUID v1'in yeni nesil halefidir.
Selefinin aksine CUID2, oluşturma zamanı, ana bilgisayar makinesi veya oluşturan süreç hakkında herhangi bir bilgi açıklamaz. Her kimlik, rastgele bir küçük harfle başlayan ve ardından SHA-512'den türetilen base-36 karmasının geldiği görünürde rastgele bir dizedir. Varsayılan uzunluk 24 karakterdir, ancak depolama kısıtlamalarınıza göre 2 ila 32 karakter arasında yapılandırabilirsiniz.
CUID2, modern veritabanı araç kitlerince yaygın olarak önerilmektedir. Prisma, @default(cuid()) skaleri için varsayılan kimlik stratejisi olarak benimsemiştir; PlanetScale, Neon ve diğer sunucusuz veritabanı sağlayıcıları, CUID2'yi otomatik artırma tam sayıların sıralı tarama güvenlik açıklarından kaçındığı için tercih edilen kimlik formatı olarak açıkça listelemektedir.
CUID2 CUID v1'in Yerini Neden Aldı
2012'de Eric Elliott tarafından yayımlanan CUID v1, istemci tarafı kimlik oluşturmada düz UUID'lere göre önemli bir iyileştirmeydi. Ancak güvenlik araştırmacıları tasarımında iki temel sorun keşfetti:
- Parmak izi: Her CUID v1 değerine gömülü ana bilgisayar parmak izi, kimlikleri gözlemleyebilen herkes için operasyonel meta verileri sızdırarak kimliği oluşturan makineyi veya süreci tanımlamak için kullanılabilirdi.
- Tahmin edilebilirlik: CUID v1 monoton artan bir sayaç ve zaman damgası segmenti içerdiğinden, birkaç kimliği gözlemleyen bir saldırgan gelecekteki kimliklerin yaklaşık aralığını tahmin edebilir ve bu da kimlikleri tek yetkilendirme denetimi olarak kullanan API'lere yönelik numaralandırma saldırılarını etkinleştirebilirdi.
- Kriptografik olmayan karma: CUID v1, modern güvenlik standartlarını karşılamayan basit ve kriptografik olmayan bir karma adımı kullandı.
Orijinal yazar Eric Elliott, CUID v1'i resmi olarak kullanım dışı ilan etti ve tüm bu sorunları çözmek için CUID2'yi sıfırdan yazdı. Yeni algoritma Web Crypto API (SHA-512) kullanır ve tüm deterministik bileşenleri ortadan kaldırarak her kimliği istatistiksel olarak diğerlerinden bağımsız kılar.
CUID2 Tasarım İlkeleri
CUID2 vs CUID v1 — Karşılaştırma
Aşağıdaki tablo, CUID2 ile artık kullanım dışı olan CUID v1 arasındaki temel farkları özetlemektedir. Şu anda CUID v1 kullanıyorsanız, CUID2'ye geçmeniz kesinlikle önerilir.
| Özellik | CUID2 | CUID v1 |
|---|---|---|
| Güvenlik | Kriptografik (SHA-512) | Kriptografik olmayan (parmak izi tabanlı) |
| Tahmin edilebilirlik | Opak — meta veri sızdırılmaz | Kimlikte zaman damgası + parmak izi görünür |
| Uzunluk | Yapılandırılabilir (2–32 karakter) | Sabit 25 karakter |
| Önek | Rastgele harf a–z | Her zaman "c" ile başlar |
| Dağılım | Düz / tekdüze | Monoton artan segmentler |
| Durum | Aktif olarak bakımı yapılıyor | Orijinal yazar tarafından kullanım dışı |
CUID2 vs UUID v4 — Karşılaştırma
UUID v4, rastgele benzersiz kimlikler için baskın standarttır. CUID2, güvenlikten ödün vermeden UUID v4'e göre çeşitli pratik avantajlar sunar.
| Özellik | CUID2 | UUID v4 |
|---|---|---|
| Varsayılan uzunluk | 24 karakter | 36 karakter (tirelerle) |
| URL güvenli | Evet — küçük harf a–z + 0–9 | Kodlama gerektirir (tire içerir) |
| Özel uzunluk | Evet (2–32) | Hayır — her zaman 128 bit / 36 karakter |
| Sıralanabilir | Hayır (tasarım gereği) | Hayır (v4 rastgeledir) |
| Entropi kaynağı | SHA-512 + Web Crypto | CSPRNG |
| Karakter seti | Base-36 (a–z, 0–9) | Hex + tireler |
Ana ödünleşme tanıdıklıktır: UUID v4, neredeyse her veritabanı, programlama dili ve API çerçevesi tarafından kutudan çıktığı gibi tanınan bir IETF standardıdır (RFC 4122). CUID2, büyüyen ancak evrensel olmayan desteğe sahip bir topluluk standardıdır. Dış sistemlerle birlikte çalışabilirlik öncelikliyse UUID v4'ü seçin; her iki ucu da kontrol ettiğinizde ve daha kısa, URL güvenli kimlikleri tercih ettiğinizde CUID2'yi seçin.
CUID2'yi Kimler Kullanıyor
CUID2, modern JavaScript ve TypeScript ekosisteminde hızlı bir şekilde benimsendi:
- Prisma — en popüler TypeScript ORM, Prisma Schema v2+'deki
@idalanları için@default(cuid())ile CUID2'yi önerilen varsayılan olarak kullanır. - PlanetScale — belgeleri ve başlangıç şablonları, dağıtılmış MySQL platformlarındaki sıralı tarama performans sorunlarından kaçınmak için uygulama tarafından oluşturulan birincil anahtarlar için CUID2'yi önerir.
- Drizzle ORM — sütun tanımları için yerleşik bir varsayılan yardımcı
cuid2()sağlar. - tRPC şablonları — birçok topluluk tRPC + Prisma başlangıç şablonu, birincil anahtar stratejisi olarak CUID2 ile birlikte gelir.
- T3 Stack — create-t3-app iskele aracı, oluşturulan şema dosyalarında CUID2 varsayılanlarıyla Prisma kullanır.
Kod Örnekleri
Resmi npm paketi @paralleldrive/cuid2 basit bir API sunar:
import { createId } from '@paralleldrive/cuid2'
// Generate a single CUID2 (default length: 24)
const id = createId()
console.log(id) // e.g. "tz4a98xxat96iws9zmbrgj3a"
// Custom length
import { init } from '@paralleldrive/cuid2'
const createShortId = init({ length: 16 })
const shortId = createShortId()
console.log(shortId) // e.g. "tz4a98xxat96iws9"Prisma şemasıyla CUID2 kullanmak:
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}npm paketi olmadan Node.js'de CUID2 oluşturmak (bu aracın tarayıcıda yaptığı gibi yalnızca Web Crypto API kullanarak):
async function generateCuid2(length = 24) {
const alphabet = 'abcdefghijklmnopqrstuvwxyz'
// Random prefix letter
const firstByte = crypto.getRandomValues(new Uint8Array(1))[0]
const firstChar = alphabet[firstByte % 26]
// Random 32-byte salt
const salt = crypto.getRandomValues(new Uint8Array(32))
const saltHex = [...salt].map(b => b.toString(16).padStart(2, '0')).join('')
// SHA-512 of timestamp + salt
const input = Date.now().toString(36) + saltHex
const hashBuffer = await crypto.subtle.digest(
'SHA-512',
new TextEncoder().encode(input)
)
// Encode hash bytes as base-36 string
const bytes = new Uint8Array(hashBuffer)
let hash = ''
for (let i = 0; i < bytes.length; i += 8) {
let chunk = 0n
for (let j = 0; j < 8 && i + j < bytes.length; j++) {
chunk = (chunk << 8n) | BigInt(bytes[i + j])
}
hash += chunk.toString(36)
}
return (firstChar + hash).slice(0, length)
}
// Usage
const id = await generateCuid2()
console.log(id) // e.g. "m7k3r9p2nxq8zt5a6cwj4bvd"