Frage

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

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

War es hilfreich?

Lösung

UUIDs (Universally Unique IDentifier), auch bekannt als GUIDs (Globally Unique IDentifier), laut RFC 4122, sind Bezeichner mit einer gewissen Eindeutigkeitsgarantie.

Der beste Weg, sie zu generieren, besteht darin, den Implementierungsanweisungen im genannten RFC zu folgen und eine der vielen von der Community geprüften Open-Source-Implementierungen zu verwenden.

Ein beliebtes Open-Source-Tool zum Arbeiten mit UUIDs in JavaScript ist Knoten-UUID

Beachten Sie, dass Sie durch die zufällige Generierung der Bezeichner Byte für Byte oder Zeichen für Zeichen nicht die gleichen Garantien erhalten wie eine konforme Implementierung.Außerdem ist es sehr wichtig, dass Systeme, die mit kompatiblen UUIDs arbeiten, sich möglicherweise dafür entscheiden, zufällig generierte UUIDs nicht zu akzeptieren, und viele Open-Source-Validatoren prüfen tatsächlich, ob eine gültige Struktur vorliegt.

Eine UUID muss dieses Format haben:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Bei dem die M Und N Positionen dürfen nur bestimmte Werte haben.Derzeit sind die einzigen gültigen Werte für M 1, 2, 3, 4 und 5, sodass die zufällige Generierung dieser Position die meisten Ergebnisse inakzeptabel machen würde.

Andere Tipps

Für eine RFC4122 Version 4-konforme Lösung, diese Einzeiler (ish) Lösung ist die kompakteste ich einfiel.

function uuidv4() {
  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);
  });
}

console.log(uuidv4())

Update, 2015.06.02 : Beachten Sie, dass UUID Einzigartigkeit stark von dem zugrunde liegenden Zufallszahlengenerator (RNG) beruht. Die Lösung oben verwendet Math.random() der Kürze halber jedoch Math.random() ist nicht garantiert eine qualitativ hochwertige RNG sein. Siehe Adam Hyland®s auf Math.random () . Für eine robuste Lösung, sollten Sie so etwas wie die UUID Modul [Disclaimer: Ich bin der Autor] , die verwendet höhere Qualität RNG-APIs, sofern verfügbar.

Update, 2015.08.26 : Als Randnotiz, diese Kern beschreibt, wie Sie feststellen, wie viele IDs können vor dem Erreichen einer bestimmten Wahrscheinlichkeit einer Kollision erzeugt werden. Zum Beispiel mit 3.26x10 15 Version 4 RFC4122 UUIDs haben Sie eine 1-in-a-million Chance einer Kollision.

Update, 2017.06.28 : A gute Artikel von Chrome-Entwicklern den Zustand Math.random PRNG Qualität in Chrome, Firefox und Safari zu diskutieren. tl; dr - Ab Ende 2015 ist es „ziemlich gut“, aber nicht kryptographische Qualität. Um dieses Problem zu beheben, ist hier eine aktualisierte Version der obigen Lösung, die ES6 verwendet, die crypto API und ein bisschen JS wizardy ich kann nicht Kredit für nehmen:

function uuidv4() {
  return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  )
}

console.log(uuidv4());

Ich mag, wie sauber Broofa Antwort ist, aber es ist bedauerlich, dass schlechte Implementierungen von Math.random die Chance für eine Kollision verlassen.

Hier ist ein ähnliches RFC4122 Version 4-konforme Lösung, die durch Versetzen der ersten diese Frage löst 13 Hexadezimalzahlen durch einen hex Teil des Zeitstempels. Auf diese Weise, auch wenn Math.random auf dem gleichen Samen ist, würde beiden Kunden haben die UUID auf die exakt gleiche Millisekunde (oder 10.000 Jahre später) zu erzeugen, um die gleiche UUID zu erhalten:

function generateUUID() { // Public Domain/MIT
    var d = new Date().getTime();
    if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
        d += performance.now(); //use high-precision timer if available
    }
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}


Hier ist eine Geige zu testen.

broofa Antwort ist ziemlich glatt, in der Tat - eindrucksvoll klug, wirklich ... RFC4122-konform, etwas lesbar und kompakt. Awesome!

Aber wenn Sie an diesem regulären Ausdruck suchen, die viele replace() Rückrufe, toString() ist und Math.random() Funktionsaufrufe (wo er nur 4 Bits des Ergebnisses verwenden und verschwendet den Rest), können Sie beginnen, um die Leistung zu fragen. Tatsächlich joelpt entschied sogar RFC für generische GUID Geschwindigkeit mit generateQuickGUID zu werfen.

Aber wir können bekommen Geschwindigkeit und RFC Compliance? Ich sage: Ja! Können wir Lesbarkeit beibehalten? Nun ... Nicht wirklich, aber es ist einfach, wenn Sie entlang folgen.

Aber zuerst, meine Ergebnisse, im Vergleich zu broofa, guid (die akzeptierte Antwort) und die nicht-RFC-kompatible generateQuickGuid:

                  Desktop   Android
           broofa: 1617ms   12869ms
               e1:  636ms    5778ms
               e2:  606ms    4754ms
               e3:  364ms    3003ms
               e4:  329ms    2015ms
               e5:  147ms    1156ms
               e6:  146ms    1035ms
               e7:  105ms     726ms
             guid:  962ms   10762ms
generateQuickGuid:  292ms    2961ms
  - Note: 500k iterations, results will vary by browser/cpu.

So von meiner 6.en Iteration von Optimierungen, schlug ich die populärste Antwort von über 12X , die akzeptierten Antwort von über 9X , und die schnell nicht konforme Antwort von 2-3X . Und ich bin immer noch RFC4122-konform.

Sie interessieren sich wie? Ich habe die volle Quelle setzt auf http://jsfiddle.net/jcward/7hyaC/3/ und http://jsperf.com/uuid-generator-opt/4

Für eine Erklärung, lassen Sie sich mit broofa Code starten:

'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);
});

So ersetzt er x mit jedem beliebigen Hexadezimalzeichens, y mit zufälligen Daten (außer zwingen die oberen 2 Bits pro RFC-Spezifikation 10) und die regex die - oder 4 Zeichen nicht überein, so tut er nicht mit ihnen beschäftigen. Sehr, sehr glatt.

Das erste, was zu wissen ist, dass Funktionsaufrufe teuer sind, als reguläre Ausdrücke sind (obwohl er nur 1 verwendet, es hat 32 Rückrufe, eine für jedes Spiel, und in jedem der 32 Rückrufe es nennt Math.random () und v.toString (16)).

Der erste Schritt zur Leistung ist die RegEx und seine Rückruffunktionen und die Verwendung eine einfache Schleife statt zu beseitigen. Dies bedeutet, dass wir mit den - und 4 Zeichen zu tun haben, während broofa nicht. Beachten Sie auch, dass wir String Array Indizierung verwenden können, seine glatten String Templatarchitektur zu halten:

function e1() {
  var u='',i=0;
  while(i++<36) {
    var c='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'[i-1],r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);
    u+=(c=='-'||c=='4')?c:v.toString(16)
  }
  return u;
}

Im Grunde genommen die gleiche innere Logik, außer wir prüfen für - oder 4 und unter Verwendung einer while-Schleife (statt replace() Rückrufe) bringt uns eine fast 3X Verbesserung!

Der nächste Schritt ist ein kleiner auf dem Desktop, sondern macht einen ordentlichen Unterschied auf dem Handy. Lassen Sie uns weniger Math.random () Anrufe und nutzen alle diese Zufallsbits anstelle des Werfens 87% von ihnen weg mit einem zufälligen Puffer machen, die jede Iteration herausgeschoben wird. Lassen Sie uns auch aus der Schleife, dass die Template-Definition verschieben, falls es hilft:

function e2() {
  var u='',m='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',i=0,rb=Math.random()*0xffffffff|0;
  while(i++<36) {
    var c=m[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
    u+=(c=='-'||c=='4')?c:v.toString(16);rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
  }
  return u
}

Das spart uns 10 bis 30%, je nach Plattform. Nicht schlecht. Aber der nächste große Schritt wird mit einer Optimierung klassischen insgesamt der toString Funktionsaufrufe zu befreien - der Look-Up-Tabelle. Eine einfache 16-Element-Lookup-Tabelle wird die Arbeit von toString (16) in viel kürzerer Zeit durchführen:

function e3() {
  var h='0123456789abcdef';
  var k='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
  /* same as e4() below */
}
function e4() {
  var h=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
  var k=['x','x','x','x','x','x','x','x','-','x','x','x','x','-','4','x','x','x','-','y','x','x','x','-','x','x','x','x','x','x','x','x','x','x','x','x'];
  var u='',i=0,rb=Math.random()*0xffffffff|0;
  while(i++<36) {
    var c=k[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
    u+=(c=='-'||c=='4')?c:h[v];rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
  }
  return u
}

Die nächste Optimierung ist ein weiterer Klassiker. Da wir nur Umgang mit 4-Bit Ausgang in jeder Schleife Iteration sie schneiden die Anzahl der Schleifen in der Mitte und Prozess 8-Bit jede Iteration. Dies ist schwierig, da wir immer noch die RFC-konformen Bit-Positionen zu behandeln, aber es ist nicht allzu schwer. Wir müssen dann eine größeren Lookup-Tabelle machen (16x16 oder 256) zu speichern 0x00 -. 0xff, und wir bauen es nur einmal außerhalb der e5 () Funktion

var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e5() {
  var k=['x','x','x','x','-','x','x','-','4','x','-','y','x','-','x','x','x','x','x','x'];
  var u='',i=0,rb=Math.random()*0xffffffff|0;
  while(i++<20) {
    var c=k[i-1],r=rb&0xff,v=c=='x'?r:(c=='y'?(r&0x3f|0x80):(r&0xf|0x40));
    u+=(c=='-')?c:lut[v];rb=i%4==0?Math.random()*0xffffffff|0:rb>>8
  }
  return u
}

habe ich versucht, eine e6 (), die 16-Bits gleichzeitig verarbeitet, noch das 256-Element-LUT verwendet, und es zeigte sich der abnehmenden Erträge der Optimierung. Obwohl es weniger Iterationen hatte, wurde die innere Logik von t komplizierter erhöhte die Verarbeitung und es erfolgte das gleiche auf dem Desktop, und nur ~ 10% schneller auf dem Handy.

Die endgültige Optimierungstechnik anzuwenden - die Schleife entrollen. Da wir eine feste Anzahl von Zeiten sind Looping, können wir alle aus dieser von Hand technisch schreiben. Ich habe versucht, dieses Mal mit einem einzigen Zufallsvariable r, dass ich die Neuzuweisung gehalten und Leistung getankt. Aber mit vier Variablen vorne Zufallsdaten zugewiesen, dann auf die Nachschlag-Tabelle, und Anwenden der richtigen RFC Bits, diese Version raucht sie alle:

var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e7()
{
  var d0 = Math.random()*0xffffffff|0;
  var d1 = Math.random()*0xffffffff|0;
  var d2 = Math.random()*0xffffffff|0;
  var d3 = Math.random()*0xffffffff|0;
  return lut[d0&0xff]+lut[d0>>8&0xff]+lut[d0>>16&0xff]+lut[d0>>24&0xff]+'-'+
    lut[d1&0xff]+lut[d1>>8&0xff]+'-'+lut[d1>>16&0x0f|0x40]+lut[d1>>24&0xff]+'-'+
    lut[d2&0x3f|0x80]+lut[d2>>8&0xff]+'-'+lut[d2>>16&0xff]+lut[d2>>24&0xff]+
    lut[d3&0xff]+lut[d3>>8&0xff]+lut[d3>>16&0xff]+lut[d3>>24&0xff];
}

Modualized: http://jcward.com/UUID.js - UUID.generate()

Das Komische ist, 16 Byte Zufallsdaten zu erzeugen ist der einfache Teil. Der ganze Trick ist es in String-Format mit RFC Compliance zum Ausdruck, und es ist am engsten mit 16 Byte Zufallsdaten, eine entrollten Schleife und Lookup-Tabelle erreicht.

Ich hoffe, meine Logik richtig ist - es ist sehr einfach, einen Fehler in dieser Art von langweiliger Bit-Arbeit zu machen. Aber die Ausgänge gut aussehen zu mir. Ich hoffe, dass Sie diese verrückte Fahrt durch Code-Optimierung genossen!

seien geraten Sie: mein primäres Ziel war es zu zeigen und mögliche Optimierungsstrategien zu lehren. Andere Antworten wichtige Themen wie Kollisionen und echten Zufallszahlen, die zur Erzeugung von gut UUIDs wichtig sind.

Hier ist ein Code basierend auf RFC 4122 , Abschnitt 4.4 (Algorithmen für eine UUID erstellen von Truly Random oder Pseudo-Random Number).

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;
}
var uniqueId = Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);

Wenn IDs erzeugt mehr als 1 Millisekunde auseinander, sie sind zu 100% einzigartig.

Wenn zwei IDs in kürzeren Abständen erzeugt werden, und unter der Annahme, dass die Zufallsmethode wirklich zufällig ist, würde diese IDs generieren, die 99,99999999999999% wahrscheinlich sind global eindeutig sein (Kollision in 1 von 10 ^ 15)

Sie können diese Zahl erhöhen, indem mehr Stellen geben, aber 100% einzigartiges IDs zu erzeugen benötigen Sie einen globalen Zähler verwenden.

Wenn Sie wirklich RFC Compliance tun müssen, diese Formatierung als gültige Version 4 GUID übergeben wird:

const uid = (new Date()).getTime().toString(16) + Math.random().toString(16).substring(2) + "0".repeat(16);
const guid = uid.substr(0,8) + '-' + uid.substr(8,4) + '-4000-8' + uid.substr(12,3) + '-' + uid.substr(15,12);

Edit: Der obige Code folgt der Intension, aber nicht die Buchstaben des RFC. Unter anderen Abweichungen ist es ein paar zufälligen Ziffern kurz. (Mehr Zufallszahlen hinzufügen, wenn Sie es brauchen) Der Vorteil ist, dass dies wirklich schnell ist, im Vergleich zu 100% konformen Code. Sie können testen Sie Ihre GUID hier

Schnellste GUID wie String-Generator-Methode im Format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. Dies gilt nicht standardkonforme GUID generieren.

Zehn Millionen Hinrichtungen dieser Implementierung nehmen nur 32,5 Sekunden, die die schnellsten, die ich je in einem Browser gesehen habe (die einzige Lösung ohne Schleifen / Iterationen).

Die Funktion ist so einfach wie:

/**
 * Generates a GUID string.
 * @returns {String} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser (slavik@meltser.info).
 * @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 sicher, die meisten von euch werden verstehen, was ich da tat, aber vielleicht gibt es mindestens eine Person, die eine Erklärung benötigen:

Der Algorithmus:

  • Die Math.random() Funktion liefert eine Dezimalzahl zwischen 0 und 1 mit 16 Stellen nach dem Dezimalbruch Punkt (für Beispiel 0.4363923368509859).
  • Dann nehmen wir diese Zahl und konvertieren es in einen String mit der Basis 16 (aus dem obigen Beispiel werden wir bekommen 0.6fb7687f).
    Math.random().toString(16).
  • Dann schneiden wir die 0. Präfix aus (0.6fb7687f => 6fb7687f) und einen String mit acht hexadezimalen bekommen Zeichen lang sein.
    (Math.random().toString(16).substr(2,8).
  • Manchmal wird die Math.random() Funktion zurückgeben kürzere Nummer (zB 0.4363), am Ende mit Nullen durch (aus dem obigen Beispiel, tatsächlich die Zahl 0.4363000000000000). Deshalb habe ich auf diese Zeichenfolge "000000000" bin anhängt (ein String mit neun Nullen) und dann wieder mit substr() Funktion Schneiden genau es neun Zeichen zu machen (Füllung Nullen rechts).
  • Der Grund für das Hinzufügen von genau neun Nullen ist wegen des schlimmsten Falles, was ist, wenn die Math.random() Funktion zurückkehrt genau 0 oder 1 (Wahrscheinlichkeit von 1/10 ^ 16 für jeden von ihnen). Deshalb haben wir neun Nullen hinzufügen benötigt, um es ("0"+"000000000" oder "1"+"000000000") und schneiden Sie sie dann aus dem zweiten Index (3. Zeichen) mit einer Länge von acht Zeichen ab. Für den Rest der Fälle, die Zugabe von Nullen wird das Ergebnis nicht schaden, weil sie es aus ohnehin schneidet.
    Math.random().toString(16)+"000000000").substr(2,8).

Die Montage:

  • Die GUID ist in folgendem Format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • I die GUID in 4 Stücke aufgeteilt, wobei jedes Stück in 2 Typen eingeteilt (oder Formate). XXXXXXXX und -XXXX-XXXX
  • Geben Sie nun mithilfe der GUID Ich baue diese 2 Typen die GUID mit Aufruf 4 Stück montieren, wie folgt:. XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX
  • zwischen diesen beiden Arten zu unterscheiden, habe ich einen Flag-Parameter zu einem Paar Schöpfer Funktion _p8(s) hinzugefügt, sagen die s Parameter die Funktion, ob Striche hinzugefügt werden soll oder nicht.
  • Schließlich bauen wir die GUID mit den folgenden Verkettungs: _p8() + _p8(true) + _p8(true) + _p8() und schicken Sie es
  • .

Link zu diesem Beitrag auf meinem Blog

Viel Spaß! : -)

Hier ist eine Kombination aus dem Top-Antwort gestimmt hat, mit einer Abhilfe für Chrome's 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);
        });
    };

auf jsbin wenn Sie möchten, um es zu testen.

Hier ist eine völlig nicht-konform, aber sehr performant Implementierung eine ASCII-safe GUID-like eindeutige Kennung zu erzeugen.

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

Erzeugt 26 [a-z0-9] Zeichen, eine UID führt, das ist kürzer und einzigartiger als RFC-konform GUIDs. Bindestriche können trivialerweise, wenn die Menschenlesbarkeit Fragen hinzugefügt werden.

Hier sind Anwendungsbeispiele und Timings für diese Funktion und einige dieser anderen Antworten auf die Frage. Der Zeitpunkt wurde unter Chrome m25 durchgeführt, 10 Millionen Iterationen je.

>>> 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');

Hier ist eine Lösung 9. Oktober datiert 2011 von einem Kommentar von Benutzer jed https : //gist.github.com/982883 :

UUIDv4 = function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)}

Dies erreicht das gleiche Ziel wie die aktuell höchsten -rated beantworten , aber in 50+ weniger Bytes durch ausnutzen Zwang, Rekursion und Exponentialnotation. Für diejenigen neugierig, wie es, hier ist die kommentierten Form einer älteren Version der Funktion funktioniert:

UUIDv4 =

function b(
  a // placeholder
){
  return a // if the placeholder was passed, return
    ? ( // a random number from 0 to 15
      a ^ // unless b is 8,
      Math.random() // in which case
      * 16 // a random number from
      >> a/4 // 8 to 11
      ).toString(16) // in hexadecimal
    : ( // or otherwise a concatenated string:
      [1e7] + // 10000000 +
      -1e3 + // -1000 +
      -4e3 + // -4000 +
      -8e3 + // -80000000 +
      -1e11 // -100000000000,
      ).replace( // replacing
        /[018]/g, // zeroes, ones, and eights with
        b // random hex digits
      )
}

sagi Shkedy technischen 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 andere Methoden, die ein ActiveX-Steuerelement beinhalten verwenden, aber bleiben Sie weg von diesen!

Edit: Ich dachte, es wert war, unter Hinweis darauf, dass keine GUID Generator eindeutige Schlüssel garantieren können (überprüfen Sie die wikipedia-Artikel ). Es gibt immer eine Chance von Kollisionen. Ein GUID einfach bietet einen ausreichend großen Universum der Tasten, um die Änderung von Kollisionen auf fast Null zu reduzieren.

Sie können mit Knoten-UUID ( https://github.com/kelektiv/node-uuid)

Einfache, schnelle Erzeugung von RFC4122 UUID.

Features:

  • Gene RFC4122 Version 1 oder 4 UUIDs
  • Läuft in node.js und Browsern.
  • Kryptographisch starker Zufall # Generation-Plattformen zu unterstützen.
  • Geringer Platzbedarf (Möchten Sie etwas kleiner? Check this out! )

Installieren NPM verwenden:

npm install uuid

oder Verwenden von UUID über Browser:

Herunterladen Raw-Datei (UUID v1): https: // roh. githubusercontent.com/kelektiv/node-uuid/master/v1.js Herunterladen Raw File (UUID v4): https://raw.githubusercontent.com /kelektiv/node-uuid/master/v4.js


Wollen Sie noch kleiner? Check this out: https://gist.github.com/jed/982883


Verwendung:

// Generate a v1 UUID (time-based)
const uuidV1 = require('uuid/v1');
uuidV1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'

// Generate a v4 UUID (random)
const uuidV4 = require('uuid/v4');
uuidV4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'

// Generate a v5 UUID (namespace)
const uuidV5 = require('uuid/v5');

// ... using predefined DNS namespace (for domain names)
uuidV5('hello.example.com', v5.DNS)); // -> 'fdda765f-fc57-5604-a269-52a7df8164ec'

// ... using predefined URL namespace (for, well, URLs)
uuidV5('http://example.com/hello', v5.URL); // -> '3bbcee75-cecc-5b56-8031-b6641c1ed1f1'

// ... using a custom namespace
const MY_NAMESPACE = '(previously generated unique uuid string)';
uuidV5('hello', MY_NAMESPACE); // -> '90123e1c-7512-523e-bb28-76fab9f2f73d'

ES6:

import uuid from 'uuid/v4';
const id = uuid();

Ein Web-Service wäre nützlich.

Schnelle Google gefunden: http://www.hoskinson.net/GuidGenerator/

Kann nicht für diese Implementierung bürgen, aber jemand muss einen Bonafide GUID Generator veröffentlichen.

Mit einer solchen Web-Service, können Sie eine REST Web-Interface entwickeln könnte, die eine GUID-Webdienst verbraucht, und es dient durch AJAX Javascript in einem Browser.

var uuid = function() {
    var buf = new Uint32Array(4);
    window.crypto.getRandomValues(buf);
    var idx = -1;
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        idx++;
        var r = (buf[idx>>3] >> ((idx%8)*4))&15;
        var v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
    });
};

EDIT:

Revisited mein Projekt, das diese Funktion wurde mit und mochte die Ausführlichkeit. -. Aber richtige Zufälligkeit erforderlich

Eine Version basiert auf Briguy37 Antwort und einige Bitoperatoren knabbern große Fenster aus dem Puffer zu extrahieren.

Sollte auf den RFC-Typen haftet 4 (random) Schema, da ich Probleme hatte zuletzt das Parsen nicht konformen UUID mit Java UUID.

Einfache JavaScript-Modul als eine Kombination aus besten Antworten in diesem Thread.

var crypto = window.crypto || window.msCrypto || null; // IE11 fix

var Guid = Guid || (function() {

  var EMPTY = '00000000-0000-0000-0000-000000000000';

  var _padLeft = function(paddingString, width, replacementChar) {
    return paddingString.length >= width ? paddingString : _padLeft(replacementChar + paddingString, width, replacementChar || ' ');
  };

  var _s4 = function(number) {
    var hexadecimalResult = number.toString(16);
    return _padLeft(hexadecimalResult, 4, '0');
  };

  var _cryptoGuid = function() {
    var buffer = new window.Uint16Array(8);
    window.crypto.getRandomValues(buffer);
    return [_s4(buffer[0]) + _s4(buffer[1]), _s4(buffer[2]), _s4(buffer[3]), _s4(buffer[4]), _s4(buffer[5]) + _s4(buffer[6]) + _s4(buffer[7])].join('-');
  };

  var _guid = function() {
    var currentDateMilliseconds = new Date().getTime();
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(currentChar) {
      var randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0;
      currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16);
      return (currentChar === 'x' ? randomChar : (randomChar & 0x7 | 0x8)).toString(16);
    });
  };

  var create = function() {
    var hasCrypto = crypto != 'undefined' && crypto !== null,
      hasRandomValues = typeof(window.crypto.getRandomValues) != 'undefined';
    return (hasCrypto && hasRandomValues) ? _cryptoGuid() : _guid();
  };

  return {
    newGuid: create,
    empty: EMPTY
  };
})();

// DEMO: Create and show GUID
console.log(Guid.newGuid());

Verbrauch:

  
    

Guid.NewGuid ()

         

"c6c2d12f-d76b-5739-e551-07e6de5b0807"

         

Guid.empty

         

"00000000-0000-0000-0000-000000000000"

  

good ol‘wikipedia gibt es einen Link zu einer JavaScript-Implementierung von UUID.

Es sieht ziemlich elegant, und vielleicht von Salzen mit einem Hash der Client-IP-Adresse verbessert werden könnte. Dieser Hash vielleicht in den HTML-Dokument serverseitige zur Verwendung durch den clientseitige Javascript eingesetzt werden könnte.

UPDATE: Die Original-Website hat einen Shuffle hat, hier ist die aktualisierte Version

Nun, hat dies eine Reihe von Antworten schon, aber leider gibt es nicht „true“ zufällig in der Menge. Die Version unten ist eine Anpassung der broofa Antwort, sondern eine „echte“ Zufallsfunktion aktualisiert und enthält die Krypto-Bibliotheken verwendet, wo verfügbar, und die Alea () fungiert als Notlösung.

  Math.log2 = Math.log2 || function(n){ return Math.log(n) / Math.log(2); }
  Math.trueRandom = (function() {
  var crypt = window.crypto || window.msCrypto;

  if (crypt && crypt.getRandomValues) {
      // if we have a crypto library, use it
      var random = function(min, max) {
          var rval = 0;
          var range = max - min;
          if (range < 2) {
              return min;
          }

          var bits_needed = Math.ceil(Math.log2(range));
          if (bits_needed > 53) {
            throw new Exception("We cannot generate numbers larger than 53 bits.");
          }
          var bytes_needed = Math.ceil(bits_needed / 8);
          var mask = Math.pow(2, bits_needed) - 1;
          // 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111

          // Create byte array and fill with N random numbers
          var byteArray = new Uint8Array(bytes_needed);
          crypt.getRandomValues(byteArray);

          var p = (bytes_needed - 1) * 8;
          for(var i = 0; i < bytes_needed; i++ ) {
              rval += byteArray[i] * Math.pow(2, p);
              p -= 8;
          }

          // Use & to apply the mask and reduce the number of recursive lookups
          rval = rval & mask;

          if (rval >= range) {
              // Integer out of acceptable range
              return random(min, max);
          }
          // Return an integer that falls within the range
          return min + rval;
      }
      return function() {
          var r = random(0, 1000000000) / 1000000000;
          return r;
      };
  } else {
      // From http://baagoe.com/en/RandomMusings/javascript/
      // Johannes Baagøe <baagoe@baagoe.com>, 2010
      function Mash() {
          var n = 0xefc8249d;

          var mash = function(data) {
              data = data.toString();
              for (var i = 0; i < data.length; i++) {
                  n += data.charCodeAt(i);
                  var h = 0.02519603282416938 * n;
                  n = h >>> 0;
                  h -= n;
                  h *= n;
                  n = h >>> 0;
                  h -= n;
                  n += h * 0x100000000; // 2^32
              }
              return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
          };

          mash.version = 'Mash 0.9';
          return mash;
      }

      // From http://baagoe.com/en/RandomMusings/javascript/
      function Alea() {
          return (function(args) {
              // Johannes Baagøe <baagoe@baagoe.com>, 2010
              var s0 = 0;
              var s1 = 0;
              var s2 = 0;
              var c = 1;

              if (args.length == 0) {
                  args = [+new Date()];
              }
              var mash = Mash();
              s0 = mash(' ');
              s1 = mash(' ');
              s2 = mash(' ');

              for (var i = 0; i < args.length; i++) {
                  s0 -= mash(args[i]);
                  if (s0 < 0) {
                      s0 += 1;
                  }
                  s1 -= mash(args[i]);
                  if (s1 < 0) {
                      s1 += 1;
                  }
                  s2 -= mash(args[i]);
                  if (s2 < 0) {
                      s2 += 1;
                  }
              }
              mash = null;

              var random = function() {
                  var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
                  s0 = s1;
                  s1 = s2;
                  return s2 = t - (c = t | 0);
              };
              random.uint32 = function() {
                  return random() * 0x100000000; // 2^32
              };
              random.fract53 = function() {
                  return random() +
                      (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
              };
              random.version = 'Alea 0.9';
              random.args = args;
              return random;

          }(Array.prototype.slice.call(arguments)));
      };
      return Alea();
  }
}());

Math.guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c)    {
      var r = Math.trueRandom() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
  });
};

Diese erstellen Version 4 UUID (erstellt von Pseudozufallszahlen):

function uuid()
{
   var chars = '0123456789abcdef'.split('');

   var uuid = [], rnd = Math.random, r;
   uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
   uuid[14] = '4'; // version 4

   for (var i = 0; i < 36; i++)
   {
      if (!uuid[i])
      {
         r = 0 | rnd()*16;

         uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
      }
   }

   return uuid.join('');
}

Hier ist ein Beispiel der UUIDs erzeugt:

682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136

JavaScript Projekt auf GitHub - https://github.com/LiosK/UUID.js

  

UUID.js Der RFC-konformen UUID-Generator für JavaScript.

     

Siehe RFC 4122 http://www.ietf.org/rfc/rfc4122.txt .

     

Funktionen Erzeugt RFC 4122 konforme UUIDs.

     

Version 4 UUID (UUID von Zufallszahlen) und die Version 1 UUIDs   (Zeitbasierte UUID) zur Verfügung.

     

UUID-Objekt ermöglicht eine Vielzahl von Zugriff auf die UUID einschließlich des Zugangs zu   die UUID Felder aus.

     

Niedrige Zeitstempel Auflösung von JavaScript wird durch gelegentliches kompensiert   Zahlen.

  // RFC 4122
  //
  // A UUID is 128 bits long
  //
  // String representation is five fields of 4, 2, 2, 2, and 6 bytes.
  // Fields represented as lowercase, zero-filled, hexadecimal strings, and
  // are separated by dash characters
  //
  // A version 4 UUID is generated by setting all but six bits to randomly
  // chosen values
  var uuid = [
    Math.random().toString(16).slice(2, 10),
    Math.random().toString(16).slice(2, 6),

    // Set the four most significant bits (bits 12 through 15) of the
    // time_hi_and_version field to the 4-bit version number from Section
    // 4.1.3
    (Math.random() * .0625 /* 0x.1 */ + .25 /* 0x.4 */).toString(16).slice(2, 6),

    // Set the two most significant bits (bits 6 and 7) of the
    // clock_seq_hi_and_reserved to zero and one, respectively
    (Math.random() * .25 /* 0x.4 */ + .5 /* 0x.8 */).toString(16).slice(2, 6),

    Math.random().toString(16).slice(2, 14)].join('-');

Eigene UUID / GUID-Generator mit einigen Extras Angepasst hier .

Ich bin mit dem folgenden Kybos Zufallszahlengenerator ein bisschen mehr kryptografisch Sound zu sein .

Unten ist mein Skript mit der Brei und Kybos Methoden von baagoe.com ausgeschlossen.

//UUID/Guid Generator
// use: UUID.create() or UUID.createSequential()
// convenience:  UUID.empty, UUID.tryParse(string)
(function(w){
  // From http://baagoe.com/en/RandomMusings/javascript/
  // Johannes Baagøe <baagoe@baagoe.com>, 2010
  //function Mash() {...};

  // From http://baagoe.com/en/RandomMusings/javascript/
  //function Kybos() {...};

  var rnd = Kybos();

  //UUID/GUID Implementation from http://frugalcoder.us/post/2012/01/13/javascript-guid-uuid-generator.aspx
  var UUID = {
    "empty": "00000000-0000-0000-0000-000000000000"
    ,"parse": function(input) {
      var ret = input.toString().trim().toLowerCase().replace(/^[\s\r\n]+|[\{\}]|[\s\r\n]+$/g, "");
      if ((/[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12}/).test(ret))
        return ret;
      else
        throw new Error("Unable to parse UUID");
    }
    ,"createSequential": function() {
      var ret = new Date().valueOf().toString(16).replace("-","")
      for (;ret.length < 12; ret = "0" + ret);
      ret = ret.substr(ret.length-12,12); //only least significant part
      for (;ret.length < 32;ret += Math.floor(rnd() * 0xffffffff).toString(16));
      return [ret.substr(0,8), ret.substr(8,4), "4" + ret.substr(12,3), "89AB"[Math.floor(Math.random()*4)] + ret.substr(16,3),  ret.substr(20,12)].join("-");
    }
    ,"create": function() {
      var ret = "";
      for (;ret.length < 32;ret += Math.floor(rnd() * 0xffffffff).toString(16));
      return [ret.substr(0,8), ret.substr(8,4), "4" + ret.substr(12,3), "89AB"[Math.floor(Math.random()*4)] + ret.substr(16,3),  ret.substr(20,12)].join("-");
    }
    ,"random": function() {
      return rnd();
    }
    ,"tryParse": function(input) {
      try {
        return UUID.parse(input);
      } catch(ex) {
        return UUID.empty;
      }
    }
  };
  UUID["new"] = UUID.create;

  w.UUID = w.Guid = UUID;
}(window || this));

Der bessere Weg:

function(
  a,b                // placeholders
){
  for(               // loop :)
      b=a='';        // b - result , a - numeric variable
      a++<36;        // 
      b+=a*51&52  // if "a" is not 9 or 14 or 19 or 24
                  ?  //  return a random number or 4
         (
           a^15      // if "a" is not 15
              ?      // genetate a random number from 0 to 15
           8^Math.random()*
           (a^20?16:4)  // unless "a" is 20, in which case a random number from 8 to 11
              :
           4            //  otherwise 4
           ).toString(16)
                  :
         '-'            //  in other cases (if "a" is 9,14,19,24) insert "-"
      );
  return b
 }

Minimiert:

function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b}

Ich wollte broofa Antwort verstehen, so dass ich es erweitert und Kommentare hinzugefügt:

var uuid = function () {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
        /[xy]/g,
        function (match) {
            /*
            * Create a random nibble. The two clever bits of this code:
            *
            * - Bitwise operations will truncate floating point numbers
            * - For a bitwise OR of any x, x | 0 = x
            *
            * So:
            *
            * Math.random * 16
            *
            * creates a random floating point number
            * between 0 (inclusive) and 16 (exclusive) and
            *
            * | 0
            *
            * truncates the floating point number into an integer.
            */
            var randomNibble = Math.random() * 16 | 0;

            /*
            * Resolves the variant field. If the variant field (delineated
            * as y in the initial string) is matched, the nibble must
            * match the mask (where x is a do-not-care bit):
            *
            * 10xx
            *
            * This is achieved by performing the following operations in
            * sequence (where x is an intermediate result):
            *
            * - x & 0x3, which is equivalent to x % 3
            * - x | 0x8, which is equivalent to x + 8
            *
            * This results in a nibble between 8 inclusive and 11 exclusive,
            * (or 1000 and 1011 in binary), all of which satisfy the variant
            * field mask above.
            */
            var nibble = (match == 'y') ?
                (randomNibble & 0x3 | 0x8) :
                randomNibble;

            /*
            * Ensure the nibble integer is encoded as base 16 (hexadecimal).
            */
            return nibble.toString(16);
        }
    );
};

ES6 Probe

const guid=()=> {
  const s4=()=> Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);     
  return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
}

Es ist nur ein einfacher AJAX-Aufruf ...

Wenn jemand noch interessiert ist, hier ist meine Lösung.

Auf der Serverseite:

[WebMethod()]
public static string GenerateGuid()
{
    return Guid.NewGuid().ToString();
}

Auf der Client-Seite:

var myNewGuid = null;
PageMethods.GenerateGuid(
    function(result, userContext, methodName)
    {
        myNewGuid = result;
    },
    function()
    {
        alert("WebService call failed.");
    }
);

Für diejenigen, die sich einen RFC4122-Version 4-konforme Lösung Geschwindigkeit Überlegungen (wenige Anrufe Math.random ()):

function UUID() {
    var nbr, randStr = "";
    do {
        randStr += (nbr = Math.random()).toString(16).substr(2);
    } while (randStr.length < 30);
    return [
        randStr.substr(0, 8), "-",
        randStr.substr(8, 4), "-4",
        randStr.substr(12, 3), "-",
        ((nbr*4|0)+8).toString(16), // [89ab]
        randStr.substr(15, 3), "-",
        randStr.substr(18, 12)
        ].join("");
}

Die obige Funktion eine ordentliche Balance zwischen Geschwindigkeit und Zufälligkeit haben sollte.

Dies wird auf Datum basiert, und ein zufälliges Suffix zu „sichern“ Einzigartigkeit. Funktioniert gut für CSS-IDs. Es gibt immer etwas, wie und ist leicht zu hacken:

uid-139410573297741

var getUniqueId = function (prefix) {
            var d = new Date().getTime();
            d += (parseInt(Math.random() * 100)).toString();
            if (undefined === prefix) {
                prefix = 'uid-';
            }
            d = prefix + d;
            return d;
        };

Ich weiß, es ist eine alte Frage. Nur der Vollständigkeit halber, wenn Ihre Umgebung Sharepoint ist, gibt es eine Nutzenfunktion SP.Guid.newGuid (

Es ist ein jQuery-Plugin, das behandelt GUIDs schön @ http://plugins.jquery.com/project/ GUID_Helper

jQuery.Guid.Value()

Gibt den Wert eines internen Guid. Wenn kein guid angegeben wurde, gibt einen neuen (Wert wird dann intern gespeichert).


jQuery.Guid.New()

Gibt einen neuen Guid und legt es Wert ist intern.


jQuery.Guid.Empty()

Gibt eine leere Guid 00000000-0000-0000-0000-000000000000.


jQuery.Guid.IsEmpty()

Gibt boolean. Wahr, wenn leer / undefined / leer / null.


jQuery.Guid.IsValid()

Gibt boolean. Wahr gültig guid, false, wenn nicht.


jQuery.Guid.Set()

Retrns Guid. Sets GUID Benutzer angegebenen Guid, wenn ungültig, gibt einen leeren guid.

Einfacher Code, crypto.getRandomValues(a) auf verwendet unterstützten Browser (IE11 +, iOS7 +, FF21 +, Chrome, Android Chrome ). Vermeidet mit Math.random() weil diese Kollisionen verursachen kann (zum Beispiel 20 Kollisionen für 4000 erzeugen UUID in einer realen Situation von http://jsbin.com/fuwigo/1 messen Leistung.

  • 8 verwendet nur für "y", weil das die Lesbarkeit des Codes vereinfacht (y 8 sein darf 9, A oder B).
  • Lizenziert unter: CC-BY-SA mit Zuschreibung
    Nicht verbunden mit StackOverflow
    scroll top