5387 Stimmen

Wie man eine GUID / UUID erstellt

Ich versuche, in JavaScript global eindeutige Bezeichner zu erstellen. Ich bin mir nicht sicher, welche Routinen in allen Browsern verfügbar sind, wie "zufällig" und gesetzt der eingebaute Zufallszahlengenerator ist, usw.

Die GUID / UUID sollte mindestens 32 Zeichen lang sein und im ASCII-Bereich bleiben, um Probleme bei der Weitergabe zu vermeiden.

38 Stimmen

GUIDs, die als Zeichenketten dargestellt werden, sind mindestens 36 und höchstens 38 Zeichen lang und entsprechen dem Muster ^\{?[a-zA-Z0-9]{36}?\}$ und sind daher immer in ASCII.

5 Stimmen

David Bau bietet einen viel besseren Zufallszahlengenerator an, der unter davidbau.com/archives/2010/01/30/ Ich habe einen etwas anderen Ansatz zur Erzeugung von UUIDs unter blogs.cozi.com/tech/2010/04/generating-uuids-in-javascript.html

1 Stimmen

Seltsam, dass das noch niemand erwähnt hat, aber der Vollständigkeit halber: Es gibt eine Fülle von guid-Generatoren auf npm Ich wette, die meisten von ihnen funktionieren auch im Browser.

193voto

Kevin Hakanson Punkte 40091

Hier ist ein Code, der auf RFC 4122 Abschnitt 4.4 (Algorithmen zur Erzeugung einer UUID aus einer echten Zufalls- oder Pseudo-Zufallszahl).

function createUUID() {
    // http://www.ietf.org/rfc/rfc4122.txt
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}

6 Stimmen

Sie sollten die Größe des Arrays vorher deklarieren, anstatt sie dynamisch zu bestimmen, wenn Sie die GUID erstellen. var s = new Array(36);

2 Stimmen

Ich glaube, es gibt einen sehr kleinen Fehler in der Zeile, die Bits 6-7 der clock_seq_hi_and_reserved auf 01 setzt. Da s[19] ein Zeichen '0' f' und kein int 0x0..0xf ist, wird (s[19] & 0x3) | 0x8 nicht zufällig verteilt sein - es wird tendenziell mehr '9's und weniger 'b's produzieren. Dies macht nur dann einen Unterschied, wenn Sie sich aus irgendeinem Grund für die Zufallsverteilung interessieren.

106voto

Slavik Meltser Punkte 8270

Dies ist die schnellste GUID-ähnliche String-Generatormethode im Format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX . Es wird keine standardkonforme GUID erzeugt.

Zehn Millionen Durchläufe dieser Implementierung dauern nur 32,5 Sekunden, was die schnellste Zeit ist, die ich je in einem Browser gesehen habe (die einzige Lösung ohne Schleifen/Wiederholungen).

Die Funktion ist so einfach wie:

/**
 * Generates a GUID string.
 * @returns {string} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser.
 * @link http://slavik.meltser.info/?p=142
 */
function guid() {
    function _p8(s) {
        var p = (Math.random().toString(16)+"000000000").substr(2,8);
        return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
    }
    return _p8() + _p8(true) + _p8(true) + _p8();
}

Um die Leistung zu testen, können Sie diesen Code ausführen:

console.time('t');
for (var i = 0; i < 10000000; i++) {
    guid();
};
console.timeEnd('t');

Ich bin mir sicher, dass die meisten von Ihnen verstehen werden, was ich da gemacht habe, aber vielleicht gibt es wenigstens eine Person, die eine Erklärung braucht:

Der Algorithmus:

  • El Math.random() Funktion gibt eine Dezimalzahl zwischen 0 und 1 mit 16 Stellen nach dem Dezimalpunkt zurück (für Beispiel 0.4363923368509859 ).
  • Dann nehmen wir diese Zahl und wandeln sie um in eine Zeichenkette zur Basis 16 um (im obigen Beispiel erhalten wir 0.6fb7687f ). Math.random().toString(16) .
  • Dann schneiden wir die 0. Präfix ( 0.6fb7687f => 6fb7687f ) und erhalten eine Zeichenkette mit acht hexadezimalen Zeichen lang. (Math.random().toString(16).substr(2,8) .
  • Manchmal ist die Math.random() Funktion wird zurückgegeben eine kürzere Zahl (zum Beispiel 0.4363 ), wegen der Nullen am Ende (im obigen Beispiel ist die Zahl eigentlich 0.4363000000000000 ). Deshalb füge ich an diese Zeichenfolge an "000000000" (eine Zeichenkette mit neun Nullen) und schneidet sie dann ab mit substr() damit es genau neun Zeichen sind (mit Nullen nach rechts).
  • Der Grund für die Hinzufügung von genau neun Nullen ist das Worst-Case-Szenario, d. h., wenn die Math.random() Funktion wird genau 0 oder 1 zurückgeben (Wahrscheinlichkeit von 1/10^16 für jeden von ihnen). Deshalb mussten wir neun Nullen anfügen ( "0"+"000000000" o "1"+"000000000" ) und schneidet ihn dann ab dem zweiten Index (drittes Zeichen) mit einer Länge von acht Zeichen ab. In den übrigen Fällen wird das Ergebnis durch das Hinzufügen von Nullen nicht beeinträchtigt, da es ohnehin abgeschnitten wird. Math.random().toString(16)+"000000000").substr(2,8) .

Die Versammlung:

  • Die GUID hat das folgende Format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX .
  • Ich habe die GUID in vier Teile aufgeteilt, wobei jeder Teil in zwei Typen (oder Formate) unterteilt ist: XXXXXXXX y -XXXX-XXXX .
  • Jetzt baue ich die GUID mit diesen beiden Typen wie folgt auf, um die GUID mit vier Teilen zusammenzusetzen: XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX .
  • Um zwischen diesen beiden Typen zu unterscheiden, habe ich einen Flag-Parameter zu einer Paarerstellungsfunktion hinzugefügt _p8(s) die s teilt der Funktion mit, ob Bindestriche hinzugefügt werden sollen oder nicht.
  • Schließlich bilden wir die GUID mit der folgenden Verkettung: _p8() + _p8(true) + _p8(true) + _p8() und geben Sie es zurück.

Link zu diesem Beitrag in meinem Blog

Viel Spaß! :-)

18 Stimmen

Diese Umsetzung ist nicht korrekt. Bestimmte Zeichen der GUID erfordern eine besondere Behandlung (z. B. muss die 13. Stelle die Zahl 4 sein).

0 Stimmen

Leicht umgeschrieben, mit fetten Pfeilfunktionen und toStr(depricated) -> toString. Außerdem wurden die Bindestriche entfernt! guid = () => { _p8 = () => {return (Math.random() * 10000000000).toString(16).substr(0,8);} return ${_p8()}${_p8()}${_p8()}${_p8()} ; };

86voto

joelpt Punkte 3891

Hier ist eine absolut nicht konforme, aber sehr leistungsfähige Implementierung zur Erzeugung eines ASCII-sicheren GUID-ähnlichen eindeutigen Bezeichners.

function generateQuickGuid() {
    return Math.random().toString(36).substring(2, 15) +
        Math.random().toString(36).substring(2, 15);
}

Erzeugt 26 [a-z0-9]-Zeichen, was eine UID ergibt, die sowohl kürzer als auch eindeutiger ist als RFC-konforme GUIDs. Bindestriche können trivialerweise hinzugefügt werden, wenn die Lesbarkeit von Bedeutung ist.

Hier finden Sie Anwendungsbeispiele und Zeitangaben für diese Funktion und einige der anderen Antworten auf diese Frage. Die Zeitmessung wurde unter Chrome m25 mit jeweils 10 Millionen Iterationen durchgeführt.

>>> generateQuickGuid()
"nvcjf1hs7tf8yyk4lmlijqkuo9"
"yq6gipxqta4kui8z05tgh9qeel"
"36dh5sec7zdj90sk2rx7pjswi2"
runtime: 32.5s

>>> GUID() // John Millikin
"7a342ca2-e79f-528e-6302-8f901b0b6888"
runtime: 57.8s

>>> regexGuid() // broofa
"396e0c46-09e4-4b19-97db-bd423774a4b3"
runtime: 91.2s

>>> createUUID() // Kevin Hakanson
"403aa1ab-9f70-44ec-bc08-5d5ac56bd8a5"
runtime: 65.9s

>>> UUIDv4() // Jed Schmidt
"f4d7d31f-fa83-431a-b30c-3e6cc37cc6ee"
runtime: 282.4s

>>> Math.uuid() // broofa
"5BD52F55-E68F-40FC-93C2-90EE069CE545"
runtime: 225.8s

>>> Math.uuidFast() // broofa
"6CB97A68-23A2-473E-B75B-11263781BBE6"
runtime: 92.0s

>>> Math.uuidCompact() // broofa
"3d7b7a06-0a67-4b67-825c-e5c43ff8c1e8"
runtime: 229.0s

>>> bitwiseGUID() // jablko
"baeaa2f-7587-4ff1-af23-eeab3e92"
runtime: 79.6s

>>>> betterWayGUID() // Andrea Turri
"383585b0-9753-498d-99c3-416582e9662c"
runtime: 60.0s

>>>> UUID() // John Fowler
"855f997b-4369-4cdb-b7c9-7142ceaf39e8"
runtime: 62.2s

Hier ist der Zeitcode.

var r;
console.time('t'); 
for (var i = 0; i < 10000000; i++) { 
    r = FuncToTest(); 
};
console.timeEnd('t');

80voto

Prestaul Punkte 79893

Von sagi shkedys technischer blog :

function generateGuid() {
  var result, i, j;
  result = '';
  for(j=0; j<32; j++) {
    if( j == 8 || j == 12 || j == 16 || j == 20)
      result = result + '-';
    i = Math.floor(Math.random()*16).toString(16).toUpperCase();
    result = result + i;
  }
  return result;
}

Es gibt auch andere Methoden, bei denen ein ActiveX Kontrolle, aber lassen Sie die Finger davon!

Ich dachte, es sei erwähnenswert, dass kein GUID-Generator eindeutige Schlüssel garantieren kann (siehe die Wikipedia-Artikel ). Es besteht immer die Möglichkeit von Kollisionen. Eine GUID bietet einfach ein ausreichend großes Universum an Schlüsseln, um die Wahrscheinlichkeit von Kollisionen auf nahezu Null zu reduzieren.

10 Stimmen

Beachten Sie, dass es sich hierbei nicht um eine GUID im technischen Sinne handelt, da sie keine Eindeutigkeit garantiert. Das kann je nach Anwendung von Bedeutung sein oder auch nicht.

3 Stimmen

Eine kurze Anmerkung zur Leistung. Diese Lösung erzeugt insgesamt 36 Zeichenfolgen, um ein einziges Ergebnis zu erhalten. Wenn die Leistung entscheidend ist, sollten Sie ein Array erstellen und wie von empfohlen zusammenfügen: tinyurl.com/y37xtx Weitere Nachforschungen ergaben, dass dies möglicherweise keine Rolle spielt, also ist es egal: tinyurl.com/3l7945

2 Stimmen

Bezüglich der Eindeutigkeit ist es erwähnenswert, dass die UUIDs der Versionen 1, 3 und 5 auf eine Art und Weise deterministisch sind, wie es die Version 4 nicht ist. Wenn die Eingaben für diese UUID-Generatoren - node id in v1, namespace und name in v3 und v5 - eindeutig sind (wie sie sein sollen), dann sind auch die resultierenden UUIDs eindeutig. Zumindest theoretisch.

71voto

ripper234 Punkte 211096

Hier ist eine Kombination der Meistgewählte Antwort mit einem Workaround für Chroms Kollisionen :

generateGUID = (typeof(window.crypto) != 'undefined' &&
                typeof(window.crypto.getRandomValues) != 'undefined') ?
    function() {
        // If we have a cryptographically secure PRNG, use that
        // https://stackoverflow.com/questions/6906916/collisions-when-generating-uuids-in-javascript
        var buf = new Uint16Array(8);
        window.crypto.getRandomValues(buf);
        var S4 = function(num) {
            var ret = num.toString(16);
            while(ret.length < 4){
                ret = "0"+ret;
            }
            return ret;
        };
        return (S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));
    }

    :

    function() {
        // Otherwise, just use Math.random
        // https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        });
    };

Sie ist über jsbin wenn Sie es testen wollen.

4 Stimmen

Beachten Sie, dass die erste Version, die Version ` window.crypto.getRandomValues , does not keep the Version 4 UUIDs format defined by RFC 4122. That is instead of xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` ergibt sich xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X