Erstellen Sie eine GUID / UUID in Java

Lesezeit: 12 Minuten

Benutzeravatar von Chris Dutrow
Chris Dutrow

Was sind einige der besten Möglichkeiten, eine GUID / UUID in Java zu erstellen?

  • Die Frage unter stackoverflow.com/questions/325443/generate-uuid-in-java bezieht sich mehr auf GUID-Kollisionen und dann darauf, wie das Äquivalent einer GUID im Java-Tech-Stack ist, was (glaube ich) mehr ist Fokus dieser Frage.

    – Jon Adams

    18. Oktober 2012 um 15:48 Uhr

java.util.UUID.randomUUID();

  • könnte es wiederholen? weil Guid sich nie wiederholen wird

    – Engel

    7. August 2013 um 14:13 Uhr

  • @angel Ja, das ist theoretisch möglich UUID.randomUUID Methode, um ein Duplikat zurückzugeben, aber das ist überhaupt keine realistische Sorge. Die Oracle/OpenJDK-Implementierung verwendet einen kryptografisch starken Zufallszahlengenerator. Angesichts dessen und angesichts der astronomische Reichweite gegeben durch so viele Bits in einer UUID, können Sie viele Millionen solcher Werte in Ihrer App generieren und trotzdem gut schlafen. Die Verwendung einer der anderen Varianten reduziert die Möglichkeit von Kollisionen noch näher an Null, da “Raum und Zeit” verwendet werden. [1] MAC-Adresse oder Name und [2] aktuelles Datum und Uhrzeit als Einschränkungen.

    – Basilikum Bourque

    16. Juli 2015 um 21:28 Uhr


  • @RenniePet Eh, wenn du so paranoid bist und beim Erstellen einer neuen Zugriff auf die Liste der bereits verwendeten IDs hast, generierst du einfach neue in a while bis Sie einen haben, der nicht in Ihrer Liste ist: p

    – Nyerguds

    5. Juli 2016 um 13:11 Uhr

  • Der Oracle-Krypto-Zufallszahlengenerator ist typischerweise ein PRNG mit einem zufälligen Startwert. Der Zufallsstartwert wird typischerweise unter Verwendung einer vom Betriebssystem bereitgestellten “Entropie”-Quelle erhalten. Wenn Sie diese Quelle herabsetzen oder kompromittieren können, erhöht sich die Wahrscheinlichkeit, dass ein Krypto-Zufallszahlengenerator dieselbe Zahl erzeugt. Es ist auch erwähnenswert, dass dem Betriebssystem auf einigen (z. B. virtualisierten) Plattformen die Entropie ausgehen kann. Es gibt “zwielichtige Hacks”, um dies zu umgehen, aber sie beinhalten eine Verschlechterung der Qualität der Entropie.

    – Stefan C

    14. September 2017 um 1:27 Uhr

  • Dies ist nicht nur ein akademisches Anliegen. Ich habe ein (ungeprüft !!) behaupten, dass jemand tat auf Probleme mit zufallsbasierten UUIDs stoßen, die nicht eindeutig sind.

    – Stefan C

    14. September 2017 um 1:29 Uhr

Benutzeravatar von Mark Byers
Markus Byers

Schauen Sie sich die an UUID-Klasse gebündelt mit Java 5 und höher.

Zum Beispiel:

  • Wenn Sie eine zufällige UUID möchten, können Sie die verwenden zufälligeUUID Methode.
  • Wenn Sie möchten, dass eine UUID mit einem bestimmten Wert initialisiert wird, können Sie die verwenden UUID-Konstruktor oder der fromString Methode.

  • Wenn Sie ein Beispiel wie Kaleb Brasee hinzufügen, wäre Ihre gute Antwort noch besser.

    – Null3

    11. Januar 2016 um 9:29 Uhr

  • Funktioniert mindestens in AndroidStudio 2.3 und auf API-Level 21 und höher. Vielleicht auch weiter hinten.

    – Raddevus

    12. Mai 2017 um 20:04 Uhr

  • TL;DR… ” UUID uuid = UUID.randomUUID(); “

    – Aviram Fireberger

    13. August 2018 um 12:22 Uhr

Benutzeravatar von Anton Belev
Anton Belev

Nur um die Antwort von Mark Byers mit einem Beispiel zu erweitern:

import java.util.UUID;

public class RandomStringUUID {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println("UUID=" + uuid.toString() );
    }
}

  • Abgewertet, da keine “erweiterten Versionen” von JSF, Spring MVC, Android und Swing bereitgestellt werden. Komm schon, warum solltest du solche “Antworten” geben?

    – Terrorrussland-tötet weiter

    24. Dezember 2021 um 8:11 Uhr

  • @fluffy und wo genau wurde in der Frage danach gefragt?

    – Anton Belev

    24. Dezember 2021 um 14:17 Uhr

Benutzeravatar von Stephen C
Stefan C

Kommt drauf an was für UUID Sie wollen.

  • Das Standard-Java UUID Klasse erzeugt Fassung 4 (zufällige) UUIDs. (AKTUALISIERENFassung 3 (Name) UUIDs können auch generiert werden.) Es kann auch mit anderen Varianten umgehen, kann sie aber nicht generieren. (In diesem Fall bedeutet “Handle” Konstrukt UUID Instanzen aus long, byte[] oder String Repräsentationen und bieten einige geeignete Accessoren.)

  • Der Java-UUID-Generator (JUG) Die Implementierung gibt vor, „alle 3 ‚offiziellen‘ UUID-Typen gemäß der Definition von zu unterstützen RFC-4122” … obwohl der RFC eigentlich 4 Typen definiert und einen 5. Typ erwähnt.

Weitere Informationen zu UUID-Typen und -Varianten finden Sie in einer guten Zusammenfassung in Wikipediaund die blutigen Details sind drin RFC 4122 und die anderen Spezifikationen.

Benutzeravatar von Basil Bourque
Basil Bourque

Die anderen Antworten sind richtig, besonders diese von Stephen C.

Außerhalb von Java erreichen

Generieren einer UUID Wert in Java ist begrenzt auf Version 4 (zufällig) wegen Sicherheitsbedenken.

Wenn Sie andere Versionen von UUIDs wünschen, besteht eine Möglichkeit darin, Ihre Java-App außerhalb von zu erreichen JVM um UUIDs zu generieren, indem Sie Folgendes aufrufen:

  • Befehlszeilenprogramm
    Gebündelt mit fast jedem Betriebssystem.
    Zum Beispiel, uuidgen gefunden in Mac OS X, BSD und Linux.
  • Datenbankserver
    Verwenden JDBC um eine auf dem Datenbankserver generierte UUID abzurufen.
    Zum Beispiel die uuid-ossp Erweiterung oft mit gebündelt Postgres. Diese Erweiterung kann die Werte der Versionen 1, 3 und 4 und zusätzlich einige Variationen generieren:
  • uuid_generate_v1mc() – generiert eine UUID der Version 1, verwendet aber eine zufällige Multicast-MAC-Adresse anstelle der echten MAC-Adresse des Computers.
  • uuid_generate_v5(namespace uuid, name text) – generiert eine UUID der Version 5, die wie eine UUID der Version 3 funktioniert, außer dass SHA-1 als Hashing-Methode verwendet wird.
  • Internetservice
    Zum Beispiel, UUID-Generator erstellt die Versionen 1 & 3 sowie Nullwerte Und GUID.

  • Ich habe einige Probleme mit Ihrer Antwort: Erstens hat sich bereits als falsch herausgestellt, dass Sie nur V4 aus der Standard-Java-Bibliothek erhalten können (V3 ist auch möglich). Zweitens lassen Sie es so klingen, als gäbe es in Java außer der Standardbibliothek keine Optionen, zusammen mit einem handgewellten “wegen Sicherheitsbedenken”. Und schließlich ist es im Allgemeinen einfach ineffizient (programmier- und/oder leistungsmäßig), von externen Quellen abhängig zu sein, wenn es innerhalb von Java viele Möglichkeiten gibt (es sei denn, Sie benötigen es natürlich in diesen, z. B. als Teil der Erstellung einer Eintrag im SQL-Server).

    – DennisK

    6. Februar 2018 um 9:25 Uhr


Diese Antwort enthält 2 Generatoren für zufallsbasierte und namensbasierte UUIDs, die mit RFC-4122 kompatibel sind. Darf gerne verwendet und geteilt werden.

ZUFÄLLIG (v4)

Diese Hilfsklasse, die zufallsbasierte UUIDs generiert:

package your.package.name;

import java.security.SecureRandom;
import java.util.Random;
import java.util.UUID;

/**
 * Utility class that creates random-based UUIDs.
 * 
 */
public abstract class RandomUuidCreator {

    private static final int RANDOM_VERSION = 4;

    /**
     * Returns a random-based UUID.
     * 
     * It uses a thread local {@link SecureRandom}.
     * 
     * @return a random-based UUID
     */
    public static UUID getRandomUuid() {
        return getRandomUuid(SecureRandomLazyHolder.THREAD_LOCAL_RANDOM.get());
    }

    /**
     * Returns a random-based UUID.
     * 
     * It uses any instance of {@link Random}.
     * 
     * @return a random-based UUID
     */
    public static UUID getRandomUuid(Random random) {

        long msb = 0;
        long lsb = 0;

        // (3) set all bit randomly
        if (random instanceof SecureRandom) {
            // Faster for instances of SecureRandom
            final byte[] bytes = new byte[16];
            random.nextBytes(bytes);
            msb = toNumber(bytes, 0, 8); // first 8 bytes for MSB
            lsb = toNumber(bytes, 8, 16); // last 8 bytes for LSB
        } else {
            msb = random.nextLong(); // first 8 bytes for MSB
            lsb = random.nextLong(); // last 8 bytes for LSB
        }

        // Apply version and variant bits (required for RFC-4122 compliance)
        msb = (msb & 0xffffffffffff0fffL) | (RANDOM_VERSION & 0x0f) << 12; // apply version bits
        lsb = (lsb & 0x3fffffffffffffffL) | 0x8000000000000000L; // apply variant bits

        // Return the UUID
        return new UUID(msb, lsb);
    }

    private static long toNumber(final byte[] bytes, final int start, final int length) {
        long result = 0;
        for (int i = start; i < length; i++) {
            result = (result << 8) | (bytes[i] & 0xff);
        }
        return result;
    }

    // Holds thread local secure random
    private static class SecureRandomLazyHolder {
        static final ThreadLocal<Random> THREAD_LOCAL_RANDOM = ThreadLocal.withInitial(SecureRandom::new);
    }

    /**
     * For tests!
     */
    public static void main(String[] args) {

        System.out.println("// Using thread local `java.security.SecureRandom` (DEFAULT)");
        System.out.println("RandomUuidCreator.getRandomUuid()");
        System.out.println();
        for (int i = 0; i < 5; i++) {
            System.out.println(RandomUuidCreator.getRandomUuid());
        }

        System.out.println();
        System.out.println("// Using `java.util.Random` (FASTER)");
        System.out.println("RandomUuidCreator.getRandomUuid(new Random())");
        System.out.println();
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            System.out.println(RandomUuidCreator.getRandomUuid(random));
        }
    }
}

Dies ist die Ausgabe:

// Using thread local `java.security.SecureRandom` (DEFAULT)
RandomUuidCreator.getRandomUuid()

'ef4f5ad2-8147-46cb-8389-c2b8c3ef6b10'
'adc0305a-df29-4f08-9d73-800fde2048f0'
'4b794b59-bff8-4013-b656-5d34c33f4ce3'
'22517093-ee24-4120-96a5-ecee943992d1'
'899fb1fb-3e3d-4026-85a8-8a2d274a10cb'

// Using `java.util.Random` (FASTER)
RandomUuidCreator.getRandomUuid(new Random())

'4dabbbc2-fcb2-4074-a91c-5e2977a5bbf8'
'078ec231-88bc-4d74-9774-96c0b820ceda'
'726638fa-69a6-4a18-b09f-5fd2a708059b'
'15616ebe-1dfd-4f5c-b2ed-cea0ac1ad823'
'affa31ad-5e55-4cde-8232-cddd4931923a'

NAMENSBASIERT (v3 und v5)

Diese Hilfsklasse, die namensbasierte UUIDs (MD5 und SHA1) generiert:

package your.package.name;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * Utility class that creates UUIDv3 (MD5) and UUIDv5 (SHA1).
 *
 */
public class HashUuidCreator {

    // Domain Name System
    public static final UUID NAMESPACE_DNS = new UUID(0x6ba7b8109dad11d1L, 0x80b400c04fd430c8L);
    // Uniform Resource Locator
    public static final UUID NAMESPACE_URL = new UUID(0x6ba7b8119dad11d1L, 0x80b400c04fd430c8L);
    // ISO Object ID
    public static final UUID NAMESPACE_ISO_OID = new UUID(0x6ba7b8129dad11d1L, 0x80b400c04fd430c8L);
    // X.500 Distinguished Name
    public static final UUID NAMESPACE_X500_DN = new UUID(0x6ba7b8149dad11d1L, 0x80b400c04fd430c8L);

    private static final int VERSION_3 = 3; // UUIDv3 MD5
    private static final int VERSION_5 = 5; // UUIDv5 SHA1

    private static final String MESSAGE_DIGEST_MD5 = "MD5"; // UUIDv3
    private static final String MESSAGE_DIGEST_SHA1 = "SHA-1"; // UUIDv5

    private static UUID getHashUuid(UUID namespace, String name, String algorithm, int version) {

        final byte[] hash;
        final MessageDigest hasher;

        try {
            // Instantiate a message digest for the chosen algorithm
            hasher = MessageDigest.getInstance(algorithm);

            // Insert name space if NOT NULL
            if (namespace != null) {
                hasher.update(toBytes(namespace.getMostSignificantBits()));
                hasher.update(toBytes(namespace.getLeastSignificantBits()));
            }

            // Generate the hash
            hash = hasher.digest(name.getBytes(StandardCharsets.UTF_8));

            // Split the hash into two parts: MSB and LSB
            long msb = toNumber(hash, 0, 8); // first 8 bytes for MSB
            long lsb = toNumber(hash, 8, 16); // last 8 bytes for LSB

            // Apply version and variant bits (required for RFC-4122 compliance)
            msb = (msb & 0xffffffffffff0fffL) | (version & 0x0f) << 12; // apply version bits
            lsb = (lsb & 0x3fffffffffffffffL) | 0x8000000000000000L; // apply variant bits

            // Return the UUID
            return new UUID(msb, lsb);

        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Message digest algorithm not supported.");
        }
    }

    public static UUID getMd5Uuid(String string) {
        return getHashUuid(null, string, MESSAGE_DIGEST_MD5, VERSION_3);
    }

    public static UUID getSha1Uuid(String string) {
        return getHashUuid(null, string, MESSAGE_DIGEST_SHA1, VERSION_5);
    }

    public static UUID getMd5Uuid(UUID namespace, String string) {
        return getHashUuid(namespace, string, MESSAGE_DIGEST_MD5, VERSION_3);
    }

    public static UUID getSha1Uuid(UUID namespace, String string) {
        return getHashUuid(namespace, string, MESSAGE_DIGEST_SHA1, VERSION_5);
    }

    private static byte[] toBytes(final long number) {
        return new byte[] { (byte) (number >>> 56), (byte) (number >>> 48), (byte) (number >>> 40),
                (byte) (number >>> 32), (byte) (number >>> 24), (byte) (number >>> 16), (byte) (number >>> 8),
                (byte) (number) };
    }

    private static long toNumber(final byte[] bytes, final int start, final int length) {
        long result = 0;
        for (int i = start; i < length; i++) {
            result = (result << 8) | (bytes[i] & 0xff);
        }
        return result;
    }

    /**
     * For tests!
     */
    public static void main(String[] args) {

        String string = "JUST_A_TEST_STRING";
        UUID namespace = UUID.randomUUID(); // A custom name space

        System.out.println("Java's generator");
        System.out.println("UUID.nameUUIDFromBytes():      '" + UUID.nameUUIDFromBytes(string.getBytes()) + "'");
        System.out.println();
        System.out.println("This generator");
        System.out.println("HashUuidCreator.getMd5Uuid():  '" + HashUuidCreator.getMd5Uuid(string) + "'");
        System.out.println("HashUuidCreator.getSha1Uuid(): '" + HashUuidCreator.getSha1Uuid(string) + "'");
        System.out.println();
        System.out.println("This generator WITH name space");
        System.out.println("HashUuidCreator.getMd5Uuid():  '" + HashUuidCreator.getMd5Uuid(namespace, string) + "'");
        System.out.println("HashUuidCreator.getSha1Uuid(): '" + HashUuidCreator.getSha1Uuid(namespace, string) + "'");
    }
}

Dies ist die Ausgabe:

// Java's generator
UUID.nameUUIDFromBytes():      '9e120341-627f-32be-8393-58b5d655b751'

// This generator
HashUuidCreator.getMd5Uuid():  '9e120341-627f-32be-8393-58b5d655b751'
HashUuidCreator.getSha1Uuid(): 'e4586bed-032a-5ae6-9883-331cd94c4ffa'

// This generator WITH name space
HashUuidCreator.getMd5Uuid():  '2b098683-03c9-3ed8-9426-cf5c81ab1f9f'
HashUuidCreator.getSha1Uuid(): '1ef568c7-726b-58cc-a72a-7df173463bbb'

ALTERNATIVER GENERATOR

Sie können auch die verwenden uuid-creator Bibliothek. Siehe diese Beispiele:

// Create a random-based UUID
UUID uuid = UuidCreator.getRandomBased();
// Create a name based UUID (SHA1)
String name = "JUST_A_TEST_STRING";
UUID uuid = UuidCreator.getNameBasedSha1(name);

Projektseite: https://github.com/f4b6a3/uuid-creator

  • Ich habe einige Probleme mit Ihrer Antwort: Erstens hat sich bereits als falsch herausgestellt, dass Sie nur V4 aus der Standard-Java-Bibliothek erhalten können (V3 ist auch möglich). Zweitens lassen Sie es so klingen, als gäbe es in Java außer der Standardbibliothek keine Optionen, zusammen mit einem handgewellten “wegen Sicherheitsbedenken”. Und schließlich ist es im Allgemeinen einfach ineffizient (programmier- und/oder leistungsmäßig), von externen Quellen abhängig zu sein, wenn es innerhalb von Java viele Möglichkeiten gibt (es sei denn, Sie benötigen es natürlich in diesen, z. B. als Teil der Erstellung einer Eintrag im SQL-Server).

    – DennisK

    6. Februar 2018 um 9:25 Uhr


Benutzeravatar von M. Dudek
M.Dudek

In vielen Fällen benötigen wir globale UUID für Objekte und insbesondere in der ereignisgesteuerten Architektur oder im Event Sourcing müssen wir Ereignisse nach Datum sortieren, aber wir benötigen keine vollständigen Informationen über Zeitstempel.

Dort können wir eine der Implementierungen von verwenden ULID welches ist lexikografisch sortierbar.

Das Format unterscheidet sich von der Standard-UUID, ist aber dennoch einfach:

example value: 01AN4Z07BY79KA1307SR9X4MV3

 01AN4Z07BY      79KA1307SR9X4MV3

|----------|    |----------------|
 Timestamp          Randomness
   48bits             80bits

Es gibt Implementierungen in viele Sprachen.

Zum Beispiel in Java gibt es einfach lib dafür.

Codebeispiel:

import de.huxhorn.sulky.ulid.ULID;

ULID ulid = new ULID();

// with current timestamp
String newId = ulid.nextULID(); 

// with selected timestamp
String newId2 = ulid.nextULID(Instant
    .parse("2021-12-01T00:00:00.00Z")
    .toEpochMilli()
); 

Mit Spring können Sie auch Bean für den ULID-Generator erstellen.

@Configuration
public class UUIDGeneratorConfig {

    @Bean
    public ULID ulidGenerator() {
        return new ULID();
    }
}
@Component
public class ULIDGenerator {

    private final ULID ulid;

    public ULIDGenerator(ULID ulid) {
        this.ulid = ulid;
    }

    public String generateUUID() {
        return ulid.nextULID();
    }

    public String generateUUID(Instant timestamp) {
        return ulid.nextULID(timestamp.toEpochMilli());
    }
}

1450030cookie-checkErstellen Sie eine GUID / UUID in Java

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy