Was sind einige der besten Möglichkeiten, eine GUID / UUID in Java zu erstellen?
Erstellen Sie eine GUID / UUID in Java
Chris Dutrow
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
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
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
Stefan C
Kommt drauf an was für UUID Sie wollen.
-
Das Standard-Java
UUID
Klasse erzeugt Fassung 4 (zufällige) UUIDs. (AKTUALISIEREN – Fassung 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” KonstruktUUID
Instanzen auslong
,byte[]
oderString
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.
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 dieuuid-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
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());
}
}
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