logo hsb.horse
← Zur Blog-Übersicht

Blog

UUID v7-Implementierungsleitfaden: Erstellen mit JavaScript, Go und Shell

Die Bitstruktur von UUID v7, Biteinstellungen von Version/Variante, Mindestimplementierung in JavaScript, Go und Shell, Prüfelemente während der Implementierung und RFC-Referenzen sind auf einer Seite organisiert. Ein praktischer Leitfaden, der die zu überprüfenden Punkte in der Generierungslogik für Entwickler zusammenfasst, die IDs sicher einführen möchten, die sich einfach in Zeitreihen sortieren lassen. Es kann zur Bestätigung vor der Implementierung verwendet werden.

Veröffentlicht: Aktualisiert:

Wir werden nur die wesentlichen Punkte zusammenfassen, die bei der Implementierung von UUID v7 erforderlich sind.
In diesem Artikel können Sie die Bitstruktur von UUID v7, das Festlegen von Version/Variante und die Mindestimplementierung in JavaScript, Go und Shell überprüfen.

UUID v7-Grundlagen

UUID v7 ist 128 Bit mit einem Millisekunden-Zeitstempel am Anfang.

FeldAnzahl der BitsRolle
timestamp48Unix-Zeit (ms)
ver40111 (v7)
rand_a12Zufälliger Wert
var210 (Variante)
rand_b62Zufälliger Wert

Mit dieser Konfiguration ist es möglich, IDs zu erstellen, die im Allgemeinen einfach nach der Generierungszeit sortiert werden können.

Gemeinsame Schritte während der Implementierung

  1. Füllen Sie zunächst 16 Bytes mit Zufallszahlen
  2. Überschreiben Sie die ersten 6 Bytes mit der aktuellen Zeit (Millisekunden).
  3. Setzen Sie 0x7 (Version) in die oberen 4 Bits von value[6]
  4. Setzen Sie 10 (Variante) auf die oberen 2 Bits von value[8]

JavaScript/TypeScript-Implementierungsbeispiel

function uuidV7Bytes(): Uint8Array {
const value = new Uint8Array(16);
crypto.getRandomValues(value);
const timestamp = BigInt(Date.now());
value[0] = Number((timestamp >> 40n) & 0xffn);
value[1] = Number((timestamp >> 32n) & 0xffn);
value[2] = Number((timestamp >> 24n) & 0xffn);
value[3] = Number((timestamp >> 16n) & 0xffn);
value[4] = Number((timestamp >> 8n) & 0xffn);
value[5] = Number(timestamp & 0xffn);
value[6] = (value[6] & 0x0f) | 0x70;
value[8] = (value[8] & 0x3f) | 0x80;
return value;
}

Go-Implementierungsbeispiel

package main
import (
"crypto/rand"
"fmt"
"time"
)
func uuidV7() ([16]byte, error) {
var value [16]byte
if _, err := rand.Read(value[:]); err != nil {
return value, err
}
timestamp := uint64(time.Now().UnixMilli())
value[0] = byte(timestamp >> 40)
value[1] = byte(timestamp >> 32)
value[2] = byte(timestamp >> 24)
value[3] = byte(timestamp >> 16)
value[4] = byte(timestamp >> 8)
value[5] = byte(timestamp)
value[6] = (value[6] & 0x0F) | 0x70
value[8] = (value[8] & 0x3F) | 0x80
return value, nil
}
func main() {
id, _ := uuidV7()
fmt.Printf("%x\n", id)
}

Shell-Skript-Implementierungsbeispiel

#!/bin/sh
uuid_v7() {
timestamp=$(date +%s)000
timestamp_hi=$((timestamp >> 16))
timestamp_lo=$((timestamp & 0xFFFF))
rand_a=0x$(LC_ALL=C tr -dc '0-9a-f' < /dev/urandom | head -c4)
ver_rand_a=$((0x7000 | (0x0FFF & rand_a)))
rand_b_hi=0x$(LC_ALL=C tr -dc '0-9a-f' < /dev/urandom | head -c4)
var_rand_hi=$((0x8000 | (0x3FFF & rand_b_hi)))
rand_b_lo=$(LC_ALL=C tr -dc '0-9a-f' < /dev/urandom | head -c12)
printf "%08x-%04x-%04x-%04x-%s\n" \
"$timestamp_hi" "$timestamp_lo" "$ver_rand_a" "$var_rand_hi" "$rand_b_lo"
}
uuid_v7

POSIX date kann Millisekunden nicht direkt verarbeiten, daher muss die Erfassungsmethode je nach Implementierungsumgebung angepasst werden.

Elemente der Implementierungsprüfung

  • Bewerten Sie das Kollisionsrisiko, wenn innerhalb derselben Millisekunde eine große Menge erzeugt wird
  • Standardisieren Sie das Format (Zeichenfolge mit Bindestrich oder 16 Bytes) auf Benutzerseite
  • Legen Sie zunächst die DB-Indexstrategie (Annahme der Zeitreihensortierung) fest

Referenzmaterialien (extern)

Zusammenfassung

Die Implementierung von UUID v7 in jeder Sprache konzentriert sich auf „Zeitstempeleinbettung + Versions-/Variantenbitmanipulation“.
Abhängig von Ihren Anforderungen können Sie zwischen der Nutzung einer vorhandenen Bibliothek oder der Erstellung einer minimalen Implementierung im eigenen Haus wählen.