web-dev-qa-db-de.com

Erstellen GUID / UUID in JavaScript?

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

Die GUID/UUID sollte aus mindestens 32 Zeichen bestehen und im Bereich ASCII bleiben, um Probleme beim Weitergeben zu vermeiden.

3519
Jason Cohen

UUIDs (Universally Unique IDentifier), auch als GUIDs (Globally Unique IDentifier) ​​bezeichnet, laut RFC 4122 sind Identifikatoren mit einer bestimmten Eindeutigkeitsgarantie.

Der beste Weg, sie zu generieren, besteht darin, die Implementierungsanweisungen in dem genannten RFC zu befolgen, eine der zahlreichen Community-geprüften Open-Source-Implementierungen zu verwenden oder für die Sprachen, in denen sie enthalten ist, die integrierte Implementierung.

Hier sind einige Beispiele für Open Source-Tools zum Arbeiten mit UUIDs für einige beliebte Programmiersprachen aufgeführt.

JavaScript

PHP

Gehen

Ruby

Python


Wenn Sie die Bezeichner Byte für Byte oder Zeichen für Zeichen zufällig generieren, erhalten Sie nicht dieselben Garantien wie eine konforme Implementierung. Sehr wichtig ist, dass Systeme, die mit kompatiblen UUIDs arbeiten, sich dafür entscheiden, zufällig generierte nicht zu akzeptieren, und viele Open-Source-Validatoren prüfen tatsächlich nach einer gültigen Struktur.

Eine UUID muss dieses Format haben:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Die Positionen M und N dürfen nur bestimmte Werte haben. Zu diesem Zeitpunkt sind die einzigen gültigen Werte für M 1, 2, 3, 4 und 5, so dass das zufällige Erzeugen dieser Position die meisten Ergebnisse nicht akzeptabel machen würde.

2098
John Millikin

Für eine RFC4122 Version 4-kompatible Lösung ist diese Ein-Liner-Lösung (ish) die kompakteste Lösung, die ich mir vorstellen könnte:

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 die UUID-Eindeutigkeit stark vom zugrunde liegenden Zufallszahlengenerator (RNG) abhängig ist. Die obige Lösung verwendet Math.random() aus Gründen der Kürze, jedoch ist Math.random()nicht garantiert ein qualitativ hochwertiger RNG. Weitere Informationen finden Sie unter ausgezeichnete Schreibweise auf Math.random () von Adam Hyland. Für eine robustere Lösung sollten Sie Folgendes in Betracht ziehen: das uuid-Modul [Disclaimer: I'm the author], bei dem RNG-APIs mit höherer Qualität verwendet werden, sofern verfügbar.

Update, 2015-08-26: In diesem Gist wird als Randnotiz beschrieben, wie Sie bestimmen können, wie viele IDs generiert werden können, bevor eine bestimmte Kollisionswahrscheinlichkeit erreicht wird. Zum Beispiel mit 3.26x10fünfzehn Version 4 RFC4122 UUIDs Sie haben eine Kollisionswahrscheinlichkeit von 1: 1 Million.

Update, 2017-06-28: Ein guter Artikel von Chrome-Entwicklern , der den Status von Math.random PRNG in Chrome, Firefox und Safari bespricht. tl; dr - Ende 2015 ist es "ziemlich gut", aber keine kryptografische Qualität. Um dieses Problem zu beheben, finden Sie hier eine aktualisierte Version der obigen Lösung, die ES6, die crypto-API und ein bisschen von JS-Wizard, für den ich keine Anerkennung gebrauchen kann verwendet:

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

3399
broofa

Ich mag wirklich, wie sauber Broofas Antwort ist, aber es ist unglücklich, dass schlechte Implementierungen von Math.random die Chance für eine Kollision lassen. 

Hier ist eine ähnliche RFC4122 Version 4-kompatible Lösung, die dieses Problem löst, indem die ersten 13 Hex-Zahlen um einen Hex-Teil des Zeitstempels versetzt werden. Auf diese Weise müssten beide Clients selbst dann, wenn sich Math.random auf dem gleichen Grund befindet, die UUID exakt in derselben Millisekunde (oder 10.000 Jahre später) erzeugen, um dieselbe 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 zum Testen.

726
Briguy37

broofas Antwort ist in der Tat ziemlich glatt - beeindruckend klug, wirklich ... rfc4122-konform, etwas lesbar und kompakt. Genial!

Wenn Sie sich jedoch diesen regulären Ausdruck, diese vielen replace() callbacks, toString()s und Math.random() function-Aufrufe ansehen (bei denen er nur 4 Bits des Ergebnisses verwendet und den Rest verschwendet), werden Sie sich vielleicht über die Leistung wundern. Joelpt entschied sich sogar, RFC für generische GUID - Geschwindigkeit mit generateQuickGUID auszuwerfen.

Aber können wir Geschwindigkeit erreichen und RFC-Konformität? Ich sage ja! Können wir die Lesbarkeit aufrechterhalten? Nun ... Nicht wirklich, aber es ist einfach, wenn Sie mitmachen.

Aber zuerst meine Ergebnisse, verglichen mit broofa, guid (der akzeptierten Antwort) und der nicht RFC-konformen 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.

Bei meiner 6. Iteration von Optimierungen schlug ich also die populärste Antwort um 12X, die akzeptierte Antwort über 9X und die schnell-nicht-konforme Antwort um 2-3X. Und ich bin immer noch rfc4122 kompatibel.

Interessiert an wie? Ich habe die vollständige Quelle auf http://jsfiddle.net/jcward/7hyaC/3/ und auf http://jsperf.com/uuid-generator-opt/4 gestellt.

Beginnen wir für eine Erklärung mit dem Code von broofa:

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

Es ersetzt also x durch eine beliebige zufällige hexadezimale Ziffer, y durch Zufallsdaten (mit Ausnahme der Erzwingung der oberen 2 Bits für 10 je RFC-Spezifikation), und der reguläre Ausdruck stimmt nicht mit den -- oder 4-Zeichen überein mit ihnen. Sehr, sehr glatt.

Das erste, was Sie wissen sollten, ist, dass Funktionsaufrufe ebenso teuer sind wie reguläre Ausdrücke (obwohl er nur 1 verwendet, hat er 32 Rückrufe, einen für jede Übereinstimmung), und in jedem der 32 Rückrufe ruft er Math.random () und v auf. toString (16)).

Der erste Schritt in Richtung Leistung besteht darin, RegEx und seine Callback-Funktionen zu entfernen und stattdessen eine einfache Schleife zu verwenden. Dies bedeutet, dass wir uns mit den -- und 4-Zeichen befassen müssen, während broofa dies nicht tat. Beachten Sie auch, dass wir die String-Array-Indexierung verwenden können, um seine schlanke String-Vorlagenarchitektur beizubehalten:

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 dieselbe innere Logik, mit der Ausnahme, dass wir nach - oder 4 suchen, und die Verwendung einer while-Schleife (anstelle von replace() callbacks) eine fast dreifache Verbesserung bringt!

Der nächste Schritt ist ein kleiner Schritt auf dem Desktop, macht aber auf dem Handy einen ordentlichen Unterschied. Lassen Sie uns weniger Math.random () - Aufrufe machen und all diese zufälligen Bits verwenden, anstatt 87% von ihnen mit einem zufälligen Puffer wegzuwerfen, der bei jeder Iteration herausgeschoben wird. Lassen Sie uns die Vorlagendefinition auch außerhalb der Schleife verschieben, falls dies hilfreich ist:

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
}

Dies spart je nach Plattform 10-30%. Nicht schlecht. Mit dem nächsten großen Schritt werden die toString-Funktionsaufrufe mit einem Optimierungsklassiker - der Look-Up-Tabelle - jedoch ganz los. Eine einfache Nachschlagetabelle mit 16 Elementen führt den Job von toString (16) in viel kürzerer Zeit durch:

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 in jeder Schleifeniteration nur eine Ausgabe von 4 Bits verarbeiten, reduzieren wir die Anzahl der Schleifen auf die Hälfte und verarbeiten jede Iteration 8 Bits. Dies ist schwierig, da wir immer noch mit den RFC-kompatiblen Bitpositionen arbeiten müssen, aber es ist nicht zu schwer. Wir müssen dann eine größere Nachschlagetabelle erstellen (16x16 oder 256), um 0x00 - 0xff zu speichern, und wir erstellen sie nur einmal außerhalb der Funktion e5 ().

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
}

Ich habe ein e6 () versucht, das 16 Bits gleichzeitig verarbeitet, wobei immer noch die 256-Element-LUT verwendet wird, und es zeigt die abnehmenden Ergebnisse der Optimierung. Obwohl es weniger Iterationen gab, wurde die innere Logik durch die erhöhte Verarbeitung kompliziert und auf Desktop-Computern genauso und auf mobilen Geräten nur etwa 10% schneller.

Die abschließende Optimierungstechnik, die angewendet werden soll - die Schleife abrollen. Da wir eine feste Anzahl von Schleifen durchlaufen, können wir das technisch alles von Hand schreiben. Ich habe dies einmal mit einer einzigen Zufallsvariablen versucht, die ich immer wieder zugewiesen habe. Da jedoch vier Variablen zufällige Daten zugewiesen wurden, die Lookup-Tabelle verwendet und die richtigen RFC-Bits verwendet wurden, raucht diese Version 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 Lustige ist, 16 Bytes Zufallsdaten zu generieren, ist der einfache Teil. Der ganze Trick ist es, ihn im String-Format mit RFC-Konformität auszudrücken. Er wird am besten mit 16 Bytes zufälliger Daten, einer unrolled Loop und einer Lookup-Tabelle erreicht.

Ich hoffe, dass meine Logik korrekt ist - es ist sehr leicht, einen Fehler in dieser Art langweiliger Kleinarbeit zu machen. Aber die Ausgaben sehen für mich gut aus. Ich hoffe, Ihnen hat diese tolle Fahrt durch die Code-Optimierung gefallen!

Seien Sie beraten: Mein Hauptziel war es, mögliche Optimierungsstrategien aufzuzeigen und zu vermitteln. Andere Antworten behandeln wichtige Themen wie Kollisionen und echte Zufallszahlen, die für die Generierung guter UUIDs wichtig sind.

353
Jeff Ward

Hier ist ein Code basierend auf RFC 4122 , Abschnitt 4.4 (Algorithmen zum Erstellen einer UUID aus einer wirklich zufälligen oder Pseudozufallszahl).

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;
}
142
Kevin Hakanson

Schnellste GUID ähnliche String-Generator-Methode im Format _XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX_. Dadurch wird keine standardkonforme GUID generiert.

Zehn Millionen Ausführungen dieser Implementierung dauern nur 32,5 Sekunden. Dies ist die schnellste, 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 ([email protected]).
 * @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 Ihnen werden verstehen, was ich dort getan habe, aber vielleicht gibt es mindestens eine Person, die eine Erklärung benötigt:

Der Algorithmus:

  • Die Funktion Math.random() gibt eine Dezimalzahl zwischen 0 und 1 mit 16 Nachkommastellen zurück (z. B. _0.4363923368509859_).
  • Dann nehmen wir diese Zahl und konvertieren sie in einen String mit der Basis 16 (im obigen Beispiel erhalten wir _0.6fb7687f_).
    Math.random().toString(16).
  • Dann schneiden wir das Präfix _0._ (_0.6fb7687f_ => _6fb7687f_) ab und erhalten eine Zeichenfolge mit acht hexadezimalen Zeichen.
    _(Math.random().toString(16).substr(2,8)_.
  • Manchmal gibt die Funktion Math.random() eine kürzere Zahl zurück (z. B. _0.4363_), da am Ende Nullen stehen (im obigen Beispiel ist die Zahl tatsächlich _0.4363000000000000_). Aus diesem Grund hänge ich an diese Zeichenfolge _"000000000"_ (eine Zeichenfolge mit neun Nullen) an und schneide sie dann mit der Funktion substr() ab, um genau neun Zeichen zu erhalten (wobei rechts Nullen stehen).
  • Der Grund für das Hinzufügen von genau neun Nullen liegt im schlimmsten Fall, wenn die Funktion Math.random() genau 0 oder 1 zurückgibt (Wahrscheinlichkeit von 1/10 ^ 16 für jede von ihnen). Deshalb mussten wir ihm neun Nullen (_"0"+"000000000"_ oder _"1"+"000000000"_) hinzufügen und ihn dann vom zweiten Index (3. Zeichen) mit einer Länge von acht Zeichen abschneiden. 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 4 Teile aufgeteilt, wobei jedes Teil in 2 Typen (oder Formate) unterteilt ist: XXXXXXXX und _-XXXX-XXXX_.
  • Jetzt erstelle ich die GUID mit diesen 2 Typen, um die GUID mit Aufruf 4 Teilen wie folgt zusammenzusetzen: XXXXXXXX _-XXXX-XXXX_ _-XXXX-XXXX_ XXXXXXXX.
  • Um zwischen diesen beiden Typen zu unterscheiden, habe ich einer Pair Creator-Funktion _p8(s) einen Flag-Parameter hinzugefügt. Der Parameter s teilt der Funktion mit, ob Bindestriche hinzugefügt werden sollen oder nicht.
  • Schließlich erstellen wir das GUID mit der folgenden Verkettung: _p8() + _p8(true) + _p8(true) + _p8(), und geben es zurück.

Link zu diesem Beitrag in meinem Blog

Viel Spaß! : -)

86
Slavik Meltser
var uniqueId = Math.random().toString(36).substring(2) 
               + (new Date()).getTime().toString(36);

document.getElementById("unique").innerHTML =
  Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
<div id="unique">
</div>

Wenn IDs im Abstand von mehr als einer Millisekunde generiert werden, sind sie zu 100% eindeutig.

Wenn zwei IDs in kürzeren Intervallen generiert werden, und unter der Annahme, dass die Zufallsmethode wirklich zufällig ist, würde dies IDs generieren, die wahrscheinlich zu 99,99999999999999% global eindeutig sind (Kollision in 1 von 10 15)

Sie können diese Zahl erhöhen, indem Sie weitere Ziffern hinzufügen. Um jedoch 100% eindeutige IDs zu generieren, müssen Sie einen globalen Zähler verwenden.

wenn Sie wirklich RFC-Konformität benötigen, wird diese Formatierung als gültige Version 4-GUID verwendet:

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

var r = (new Date()).getTime().toString(16) + Math.random().toString(16).substring(2) + "0".repeat(16);
var guid = r.substr(0,8) + '-' + r.substr(8,4) + '-4000-8' + r.substr(12,3) + '-' + r.substr(15,12);
document.getElementById("unique").innerHTML = guid;
<div id="unique">
</div>

Edit: Der obige Code folgt der Absicht, nicht jedoch dem Buchstaben des RFC. Unter anderem sind einige zufällige Ziffern kurz. (Fügen Sie bei Bedarf weitere Zufallszahlen hinzu.) Der Vorteil ist, dass dies im Vergleich zu 100% -igem Code wirklich schnell ist Sie können hier Ihre GUID hier testen

81
Simon Rigét

Hier ist eine Kombination aus der Top-gestimmten Antwort , mit einem Workaround für Chrome-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);
        });
    };

Bei Jsbin wenn du es testen willst.

60
ripper234

Hier ist eine Lösung vom 9. Oktober 2011 aus einem Kommentar des Benutzers jed unter 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)}

Damit wird dasselbe Ziel erreicht wie mit der - aktuellsten Antwort , jedoch in mehr als 50 Bytes weniger, indem Zwang, Rekursion und exponentielle Notation genutzt werden. Für diejenigen, die wissen wollen, wie es funktioniert, hier die kommentierte Form einer älteren Version der Funktion:

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
      )
}
55
Jed Schmidt

Hier ist eine vollständig nicht kompatible, aber sehr performante Implementierung zum Generieren 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, wodurch eine UID entsteht, die sowohl kürzer als auch eindeutiger als RFC-kompatible GUIDs ist. Bindestriche können unbedeutend hinzugefügt werden, wenn es auf die Lesbarkeit von Personen ankommt.

Hier sind Verwendungsbeispiele und Timings für diese Funktion sowie einige andere Antworten dieser Frage. Das Timing 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 Timing-Code.

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

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

Einfache, schnelle Erzeugung von RFC4122 UUIDS.

Eigenschaften:

  • Generieren Sie UCIDs der Version 1 oder Version 4 von RFC4122
  • Läuft in node.js und Browsern.
  • Kryptografisch starke Zufallsgenerierung auf unterstützten Plattformen.
  • Kleiner Fußabdruck (Willst du etwas kleiner? Schau dir das an! )

Mit NPM installieren:

npm install uuid

Oder Verwenden von uuid über den Browser:

Laden Sie die Rohdatei (uuid v1) herunter: https://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.js Laden Sie die Rohdatei (uuid v4): https: // raw.githubusercontent.com/kelektiv/node-uuid/master/v4.js


Willst du noch kleiner? Überprüfen Sie dies: https://Gist.github.com/jed/982883


Verwendungszweck:

// 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();
32
Kyros Koh

Aus dem technischen Blog von sagi shkedy :

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, bei denen ein ActiveX-Steuerelement verwendet wird, aber halten Sie sich davon fern!

Edit: Ich dachte, es lohnt sich darauf hinzuweisen, dass kein GUID - Generator eindeutige Schlüssel garantieren kann (siehe den Wikipedia-Artikel ). Es besteht immer die Möglichkeit von Kollisionen. Eine GUID bietet einfach ein ausreichend großes Schlüsseluniversum, um die Änderung von Kollisionen auf nahezu null zu reduzieren.

31
Prestaul

Ein Webservice wäre nützlich. 

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

Ich kann für diese Implementierung nicht bürgen, aber SOMEONE muss einen guten Code GUID generieren.

Mit einem solchen Webdienst könnten Sie eine REST - Weboberfläche entwickeln, die den GUID - Webdienst verwendet und über AJAX Javascript in einem Browser bereitstellt.

30
Sean
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);
    });
};

BEARBEITEN:

Überarbeitete mein Projekt, das diese Funktion verwendete und die Ausführlichkeit nicht mochte. - Aber brauchte richtige Zufälligkeit.

Eine auf Briguy37s Antwort basierende Version und einige bitweise Operatoren, um nibblegroße Fenster aus dem Puffer zu extrahieren.

Sollte sich an das (zufällige) RFC-Typ 4-Schema halten, da ich beim letzten Mal Probleme hatte, nicht kompatible Uuids mit der UUID von Java zu analysieren.

29
sleeplessnerd

Einfaches JavaScript-Modul als Kombination der 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());

Verwendungszweck: 

Guid.newGuid ()

c6c2d12f-d76b-5739-e551-07e6de5b0807

Guid.empty

"00000000-0000-0000-0000-000000000000"

28
kayz1

Von good ol 'wikipedia gibt es einen Link zu einer Javascript-Implementierung von UUID.

Es sieht ziemlich elegant aus und könnte vielleicht durch Salzung mit einem Hash der IP-Adresse des Clients verbessert werden. Dieser Hash kann möglicherweise in die HTML-Dokument-Serverseite eingefügt werden, um von dem clientseitigen Javascript verwendet zu werden.

UPDATE: Die ursprüngliche Site hat einen Shuffle gehabt, hier ist die aktualisierte Version

23
Dan

Nun, das hat schon eine Menge Antworten, aber leider gibt es keine "echte" Zufallsauswahl. Die nachstehende Version ist eine Anpassung der Antwort von broofa, wurde jedoch so aktualisiert, dass sie eine "echte" Zufallsfunktion enthält, die Krypto-Bibliotheken verwendet, sofern verfügbar, und die Alea () - Funktion als Fallback.

  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 <[email protected]>, 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 <[email protected]>, 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);
  });
};
23
jvenema

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

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

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

Features Erzeugt RFC 4122-kompatible UUIDs.

UUIDs der Version 4 (UUIDs von Zufallszahlen) und UUIDs der Version 1 (zeitbasierte UUIDs) sind verfügbar.

Das UUID-Objekt ermöglicht verschiedene Zugriffe auf die UUID, einschließlich des Zugriffs auf die UUID-Felder.

Eine niedrige Zeitstempelauflösung von JavaScript wird durch zufälliges .__ kompensiert. Zahlen.

21

Diese UUID der Version 4 (erstellt aus Pseudo-Zufallszahlen)

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 generierten UUIDs:

682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136
20
Mathieu Pagé
  // 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('-');
16
jablko

Mein eigener UUID/GUID Generator wurde mit einigen Extras hier eingestellt.

Ich benutze den folgenden Kybos Zufallszahlengenerator, um ein wenig kryptographisch solider zu sein.

Unten ist mein Skript mit den Mash- 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 <[email protected]>, 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));
13
Tracker1

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}
12
Andrea Turri

Ich wollte die Antwort von broofa verstehen, also erweiterte ich sie und fügte Kommentare hinzu:

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);
        }
    );
};
12
Andrew

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()}`;
}
11

Es ist nur ein einfacher AJAX Aufruf ...

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

Auf der Serverseite:

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

Auf der Kundenseite:

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

Für alle, die eine rfc4122 Version 4-kompatible Lösung mit Überlegungen zur Geschwindigkeit wünschen (einige Aufrufe von 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 sollte ein ausgewogenes Verhältnis zwischen Geschwindigkeit und Zufälligkeit aufweisen.

11
John Fowler

Es gibt ein jQuery-Plugin, mit dem Guids @ http://plugins.jquery.com/project/GUID_Helper

jQuery.Guid.Value()

Gibt den Wert der internen Guid zurück. Wenn keine Guid angegeben wurde, wird eine neue zurückgegeben (der Wert wird dann intern gespeichert).


jQuery.Guid.New()

Gibt eine neue Guid zurück und legt sie intern fest.


jQuery.Guid.Empty()

Gibt eine leere Guid 00000000-0000-0000-00000000000000 zurück.


jQuery.Guid.IsEmpty()

Gibt boolean zurück. True wenn leer/undefiniert/leer/null.


jQuery.Guid.IsValid()

Gibt boolean zurück. Richtige gültige Guid, falsch, wenn nicht.


jQuery.Guid.Set()

Retrns Guid. Legt die Guid auf eine vom Benutzer angegebene Guid fest. Wenn diese ungültig ist, wird eine leere Guid zurückgegeben.

10
Levitikon

Ich weiß, es ist eine alte Frage. Der Vollständigkeit halber gibt es eine Dienstprogrammfunktion mit dem Namen SP.Guid.newGuid ( msdn link ), die eine neue GUID erstellt. Diese Funktion befindet sich in der Datei sp.init.js. Wenn Sie diese Funktion neu schreiben (um andere Abhängigkeiten von anderen privaten Funktionen zu entfernen), sieht das so aus:

var newGuid = function () {
    var result = '';
    var hexcodes = "0123456789abcdef".split("");

    for (var index = 0; index < 32; index++) {
        var value = Math.floor(Math.random() * 16);

        switch (index) {
        case 8:
            result += '-';
            break;
        case 12:
            value = 4;
            result += '-';
            break;
        case 16:
            value = value & 3 | 8;
            result += '-';
            break;
        case 20:
            result += '-';
            break;
        }
        result += hexcodes[value];
    }
    return result;
};
10
Anatoly Mironov

Dieses basiert auf dem Datum und fügt ein zufälliges Suffix hinzu, um die Eindeutigkeit zu gewährleisten Funktioniert gut mit css-Bezeichnern Es gibt immer etwas zurück 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;
        };
9
ling

Einfacher Code, der crypto.getRandomValues(a) in unterstützten Browsern verwendet (IE11 +, iOS7 +, FF21 +, Chrome, Android Chrome). Vermeidet die Verwendung von Math.random(), da dies zu Kollisionen führen kann (beispielsweise 20 Kollisionen für 4000 Uuids, die in einer realen Situation von Muxa erzeugt wurden).

function uuid() {
    function randomDigit() {
        if (crypto && crypto.getRandomValues) {
            var rands = new Uint8Array(1);
            crypto.getRandomValues(rands);
            return (rands[0] % 16).toString(16);
        } else {
            return ((Math.random() * 16) | 0).toString(16);
        }
    }
    var crypto = window.crypto || window.msCrypto;
    return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit);
}

Anmerkungen:

  • Optimiert für die Lesbarkeit von Code und nicht für Geschwindigkeit, also für einige hundert Uuids pro Sekunde geeignet. Erzeugt etwa 10000 Uuid () pro Sekunde in Chromium auf meinem Laptop mit http://jsbin.com/fuwigo/1 , um die Leistung zu messen.
  • Verwendet nur 8 für "y", da dies die Lesbarkeit von Code vereinfacht (y darf 8, 9, A oder B sein).
6
robocat

Wenn Sie nur eine zufällige 128-Bit-Zeichenfolge in keinem bestimmten Format benötigen, können Sie Folgendes verwenden:

function uuid() {
    return crypto.getRandomValues(new Uint32Array(4)).join('-');
}

Was wird etwas wie 2350143528-4164020887-938913176-2513998651 zurückgeben.

6
Jonathan Potter

Es ist wichtig, dass Sie gut getesteten Code verwenden, der von mehr als 1 Mitwirkenden gepflegt wird, anstatt Ihre eigenen Sachen dafür zu peitschen. Dies ist einer der Orte, an denen Sie wahrscheinlich stabilsten Code bevorzugen möchten, als die kürzeste mögliche clevere Version, die im X-Browser funktioniert, aber nicht die Eigenheiten von Y berücksichtigt, die oft dazu führen würde, dass Fehler nur als zufällig untersucht werden für einige Benutzer. Persönlich verwende ich uuid-js unter https://github.com/aurigadl/uuid-js . Welche Bower-Funktion aktiviert ist, damit ich Updates problemlos mitnehmen kann.

5
Shital Shah

Nur noch eine lesbarere Variante mit nur zwei Mutationen.

function uuid4()
{
  function hex (s, b)
  {
    return s +
      (b >>> 4   ).toString (16) +  // high nibble
      (b & 0b1111).toString (16);   // low nibble
  }

  let r = crypto.getRandomValues (new Uint8Array (16));

  r[6] = r[6] >>> 4 | 0b01000000; // Set type 4: 0100
  r[8] = r[8] >>> 3 | 0b10000000; // Set variant: 100

  return r.slice ( 0,  4).reduce (hex, '' ) +
    r.slice ( 4,  6).reduce (hex, '-') +
    r.slice ( 6,  8).reduce (hex, '-') +
    r.slice ( 8, 10).reduce (hex, '-') +
    r.slice (10, 16).reduce (hex, '-');
}
5
ceving

Ich verwende diese Funktion, ich hoffe, es kann nützlich sein.

    function NewGuid()
         {
           var sGuid="";
           for (var i=0; i<32; i++)
            {
              sGuid+=Math.floor(Math.random()*0xF).toString(0xF);
            }
           return sGuid;
         }
3
Giridhar

Sie können das npm-Paket guid, einen Guid-Generator und einen Validator verwenden.

https://www.npmjs.com/package/guid

Beispiel:

Guid.raw();
// -> '6fdf6ffc-ed77-94fa-407e-a7b86ed9e59d'

UPDATE: Dieses Paket ist veraltet. Verwenden Sie stattdessen uuid

https://www.npmjs.com/package/uuid

Beispiel: 

const uuidv4 = require('uuid/v4');
uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'
3
andersh

Für den Fall, dass jemand, der bei Google kauft, eine kleine Hilfsprogrammbibliothek sucht, erfüllt ShortId ( https://www.npmjs.com/package/shortid ) alle Anforderungen dieser Frage. Erlaubt die Angabe von zulässigen Zeichen und Längen und garantiert nicht sequentielle, sich nicht wiederholende Zeichenfolgen.

Um dies zu einer echten Antwort zu machen, verwendet der Kern dieser Bibliothek die folgende Logik, um seine kurzen IDs zu erzeugen:

function encode(lookup, number) {
    var loopCounter = 0;
    var done;

    var str = '';

    while (!done) {
        str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );
        done = number < (Math.pow(16, loopCounter + 1 ) );
        loopCounter++;
    }
    return str;
}

/** Generates the short id */
function generate() {

    var str = '';

    var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);

    if (seconds === previousSeconds) {
        counter++;
    } else {
        counter = 0;
        previousSeconds = seconds;
    }

    str = str + encode(alphabet.lookup, version);
    str = str + encode(alphabet.lookup, clusterWorkerId);
    if (counter > 0) {
        str = str + encode(alphabet.lookup, counter);
    }
    str = str + encode(alphabet.lookup, seconds);

    return str;
}

Ich habe dies nicht so editiert, dass nur die grundlegendsten Teile dieses Ansatzes widerspiegelt, daher enthält der obige Code einige zusätzliche Logik aus der Bibliothek. Wenn Sie sich für alles interessieren, was Sie tun, schauen Sie sich die Quelle an: https://github.com/dylang/shortid/tree/master/lib

3
MaxPRafferty

Ich fand dieses Skript für die Erstellung von GUIDs in JavaScript hilfreich

https://github.com/addui/GUIDJS

var myGuid = GUID();
3
Dustin Poissant

Für diejenigen, die Javascript unter Windows verwenden (z. B. WScript/CScript/MSHTA). Man kann ActiveX verwenden. Insbesondere das Scriptlet.Typelib-Objekt:

WScript.Echo((new ActiveXObject("Scriptlet.TypeLib")).Guid)

Beachten Sie, dass diese Antwort nur für die von mir aufgelisteten Technologien funktioniert. Sie funktioniert mit keinem Browser, auch nicht mit Microsoft Edge! Ihre Laufleistung hängt also von dieser Antwort ab.

2
Stephen Quan

Für meinen Anwendungsfall benötigte ich eine ID-Generierung, die garantiert weltweit einzigartig ist. ohne Ausnahme. Ich hatte eine Weile mit dem Problem zu kämpfen und kam zu einer Lösung namens tuid (Truly Unique ID). Es generiert eine ID, wobei die ersten 32 Zeichen vom System generiert werden und die verbleibenden Ziffern Millisekunden seit Epoche darstellen. In Situationen, in denen ich IDs auf clientseitigem Javascript generieren muss, funktioniert es gut. Guck mal:

https://github.com/mongoh/tuid

2
Rishi

Hallo, hier ist ein Arbeitsbeispiel, das 32-stellige eindeutige UUID generiert. 

function generateUUID() {
      var d = new Date();
      var k = d.getTime();
     var str = k.toString(16).slice(1)
    var UUID= 'xxxx-xxxx-4xxx-yxxx-xzx'.replace(/[xy]/g, function (c)
      {
        var r = Math.random() * 16 | 0;
        v = c == 'x' ? r : (r & 3 | 8);
        return v.toString(16);
      });
      var newString = UUID.replace(/[z]/, str)
      return newString;
    }
    var x = generateUUID()
    console.log(x,x.length)
2
Ashish Yadav

Ich konnte keine Antwort finden, die ein einzelnes 16-Oktett TypedArray und eine DataView verwendet. Daher denke ich, dass die folgende Lösung zum Generieren einer UUID der Version 4 pro der RFC hier alleine stehen wird:

function uuid4() {
    const ho = (n, p) => n.toString(16).padStart(p, 0); /// Return the hexadecimal text representation of number `n`, padded with zeroes to be of length `p`
    const view = new DataView(new ArrayBuffer(16)); /// Create a view backed by a 16-byte buffer
    crypto.getRandomValues(new Uint8Array(view.buffer)); /// Fill the buffer with random data
    view.setUint8(6, (view.getUint8(6) & 0xf) | 0x40); /// Patch the 6th byte to reflect a version 4 UUID
    view.setUint8(8, (view.getUint8(8) & 0x3f) | 0x80); /// Patch the 8th byte to reflect a variant 1 UUID (version 4 UUIDs are)
    return `${ho(view.getUint32(0), 8)}-${ho(view.getUint16(4), 4)}-${ho(view.getUint16(6), 4)}-${ho(view.getUint16(8), 4)}-${ho(view.getUint32(10), 8)}${ho(view.getUint16(14), 4)}`; /// Compile the canonical textual form from the array data
}

Ich bevorzuge es, weil es nur auf Funktionen der ECMAScript-Standardplattform angewiesen ist.

1
amn

basierend auf der Arbeit von broofa habe ich etwas mehr Zufall hinzugefügt, indem ich den Zeitstempel zu math.random () 

Hoffe es könnte helfen

function uuidv4() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = parseFloat('0.' + Math.random().toString().replace('0.', '') + new Date().getTime()) * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}
1
freecloud

Hier finden Sie eine sehr kleine Funktion, die Uuids generiert https://Gist.github.com/jed/982883

Eine der letzten Versionen ist:

function b(
  a                  // placeholder
){
  var cryptoObj = window.crypto || window.msCrypto; // for IE 11
  return a           // if the placeholder was passed, return
    ? (              // a random number from 0 to 15
      a ^            // unless b is 8,
      cryptoObj.getRandomValues(new Uint8Array(1))[0]  // 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
      )
}
1
Pablo Pazos

Eine einfache Lösung zum Generieren einer eindeutigen Identifikation besteht darin, das Zeit-Token zu verwenden und eine Zufallszahl hinzuzufügen. Ich bevorzuge es, "uuid-" vorzustellen.

Die folgende Funktion generiert eine zufällige Zeichenfolge des Typs: uuid-14d93eb1b9b4533e6 . Man muss keine 32-Zeichen-Zufallszeichenfolge generieren. Eine zufällige Zeichenfolge von 16 Zeichen ist in diesem Fall mehr als ausreichend, um die eindeutigen UUIDs in Javascript bereitzustellen.

 var createUUID = Funktion () {
 return "uuid -" + ((neues Datum) .getTime (). toString (16) + Math.floor (1E7 * Math.random ()). toString (16)); 
} 
0
mangalbhaskar

OK, mit dem Paket uuid wird die Unterstützung für version 1, 3, 4 und 5 UUIDs unterstützt:

yarn add uuid

und dann:

const uuidv1 = require('uuid/v1');
uuidv1(); // ⇨ '45745c60-7b1a-11e8-9c9c-2d42b21b1a3e'

Sie können dies auch mit vollständig festgelegten Optionen tun:

const v1options = {
  node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
  clockseq: 0x1234,
  msecs: new Date('2011-11-01').getTime(),
  nsecs: 5678
};
uuidv1(v1options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab'

Für weitere Informationen besuchen Sie die npm-Seite hier

0
Alireza

Ich dachte nur, ich würde noch eine andere Möglichkeit posten, das Gleiche zu tun.

function guid() {
  var chars = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
  var str = "";
  for(var i=0;i<36;i++) {
    var str = str + ((i == 8 || i == 13 || i == 18 || i == 23) ? "-" : chars[Math.floor(Math.random()*chars.length)]);
  };
  return str;
}
0
Matthew Riches

Dies kann für jemanden nützlich sein ...

var d = new Date().valueOf();
var n = d.toString();
var result = '';
var length = 32;
var p = 0;
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

for (var i = length; i > 0; --i){
    result += ((i & 1) && n.charAt(p) ? '<b>' + n.charAt(p) + '</b>' : chars[Math.floor(Math.random() * chars.length)]);
    if(i & 1) p++;
};

https://jsfiddle.net/j0evrdf1/1/

0
lugreen
function randomHex(length) {
    var random_string = '';
    if(!length){
        length = 1;
    }
    for(var i=0; i<length; i+=1){
        random_string += Math.floor(Math.random() * 15).toString(16);
    }
    return random_string;
}

function guid() {
    return randomHex(8);
}
0
JHG

Wir können replace und crypto.getRandomValues ​​verwenden, um eine Ausgabe wie die folgende zu erhalten:

xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx

 enter image description here

Wenn wir nach einer optimalen Lösung suchen, müssen wir crypto.getRandomValues(new Uint8Array(1))[0] durch ein Array (32) ersetzen.

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

console.log(uuidv4());

So erhalten Sie diesen Code:

function uuidv4() {
  let bytes = window.crypto.getRandomValues(new Uint8Array(32));
  const randomBytes = () => (bytes = bytes.slice(1)) && bytes[0];

  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => 
      (c ^ randomBytes() & 15 >> c / 4).toString(16)
    );
}


for (var i = 0; i < 10; i++)
  console.log(uuidv4());

Kollision:

Wir können wie bei Google Analytics vorgehen und einen Zeitstempel hinzufügen mit: uuidv4() + "." + (+new Date()).

0
A-312

Für die Wissenschaft. Ich habe noch niemanden gesehen, der dies tut ... er ist nicht v4-konform, könnte aber leicht geändert werden. Dies ist nur ein Beispiel für die Erweiterung des Typs Uint8Array und die Verwendung von crypto.getRandomValues ​​() zum Generieren der uuid-Bytewerte.

class uuid extends Uint8Array {
        constructor() {
            super(16)
            /* not v4, just some random bytes */
            window.crypto.getRandomValues(this)
        }
        toString() {
            let id = new String()
            for (let i = 0; i < this.length; i++) {
                /*convert uint8 to hex string */
                let hex = this[i].toString(16).toUpperCase()

                /*add zero padding*/
                while (hex.length < 2) {
                    hex = String(0).concat(hex)
                }
                id += hex

                /* add dashes */
                if (i == 4 || i == 6 || i == 8 || i == 10 || i == 16){
                    id += '-'
                }
            }
            return id
        }
    }
0
Jacob Ochoa