Een GUID / UUID maken

Ik probeer wereldwijd unieke ID’s te maken in JavaScript. Ik weet niet zeker welke routines beschikbaar zijn in alle browsers, hoe “willekeurig” en gezaaid de ingebouwde generator voor willekeurige getallen is, enz.

De GUID / UUID moet minimaal 32 tekens lang zijn en binnen het ASCII-bereik blijven om problemen bij het doorgeven ervan te voorkomen.


Antwoord 1, autoriteit 100%

UUID’s (Universally Unique IDentifier), ook bekend als GUID’s (Globally Unique IDentifier), volgens RFC 4122, zijn identifiers die zijn ontworpen om bepaalde uniciteitsgaranties te bieden.

Hoewel het mogelijk is om RFC-compatibele UUID’s te implementeren in een paar regels JavaScript-code (zie bijvoorbeeld @broofa’s antwoord, hieronder) zijn er verschillende veelvoorkomende valkuilen:

  • Ongeldige id-indeling (UUID’s moeten de vorm “xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx” hebben, waarbij x een van [0-9, af] M is een van [1-5] en N is [8, 9, a of b]
  • Gebruik van een bron van willekeur van lage kwaliteit (zoals Math.random)

Ontwikkelaars die code schrijven voor productieomgevingen worden dus aangemoedigd om een ​​rigoureuze, goed onderhouden implementatie te gebruiken, zoals de uuid-module.


Antwoord 2, autoriteit 86%

Voor een RFC4122 versie 4 compatibele oplossing, deze one-liner(ish) oplossing is de meest compacte die ik kon bedenken:

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

Antwoord 3, autoriteit 34%

Ik vind het echt leuk hoe schoon Broofa’s antwoord is, maar het is jammer dat slechte implementaties van Math.random laten de kans op een botsing bestaan.

Hier is een vergelijkbare RFC4122 versie 4 compatibele oplossing die dat probleem oplost door de eerste te compenseren 13 hexadecimale getallen door een hex-gedeelte van de tijdstempel, en eenmaal uitgeputte offsets met een hex-gedeelte van de microseconden sinds het laden van de pagina. Op die manier, zelfs als Math.random zich op dezelfde seed bevindt, zouden beide clients de UUID hetzelfde aantal microseconden moeten genereren sinds het laden van de pagina (als high-performance tijd wordt ondersteund) EN op exact hetzelfde dezelfde milliseconde (of 10.000+ jaar later) om dezelfde UUID te krijgen:

function generateUUID() { // Public Domain/MIT
    var d = new Date().getTime();//Timestamp
    var d2 = (performance && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16;//random number between 0 and 16
        if(d > 0){//Use timestamp until depleted
            r = (d + r)%16 | 0;
            d = Math.floor(d/16);
        } else {//Use microseconds since page-load if supported
            r = (d2 + r)%16 | 0;
            d2 = Math.floor(d2/16);
        }
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}
var onClick = function(){
    document.getElementById('uuid').textContent = generateUUID();
}
onClick();
#uuid { font-family: monospace; font-size: 1.5em; }
<p id="uuid"></p>
<button id="generateUUID" onclick="onClick();">Generate UUID</button>

Antwoord 4, autoriteit 19%

broofa’s antwoord is inderdaad behoorlijk gelikt – indrukwekkend slim, echt… RFC4122-compatibel, enigszins leesbaar en compact. Geweldig!

Maar als je naar die reguliere expressie kijkt, die vele replace() callbacks, toString()‘s en Math.random() functie-aanroepen (waar hij slechts vier bits van het resultaat gebruikt en de rest verspilt), begin je je misschien af ​​te vragen over de prestaties. Joelpt besloot zelfs om een ​​RFC weg te gooien voor generieke GUID-snelheid met generateQuickGuid.

Maar kunnen we snelheid en RFC-compliance krijgen? Ik zeg JA! Kunnen we de leesbaarheid behouden? Nou… Niet echt, maar het is gemakkelijk als je meegaat.

Maar eerst, mijn resultaten, vergeleken met broofa, guid (het geaccepteerde antwoord), en de niet-rfc-conforme 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.

Dus door mijn 6e herhaling van optimalisaties versloeg ik het meest populaire antwoord met meer dan 12 keer, het geaccepteerde antwoord met meer dan 9 keer en het snelle-niet- compliant antwoord met 2 tot 3 keer. En ik ben nog steeds RFC 4122-compatibel.

Geïnteresseerd in hoe? Ik heb de volledige bron op http://jsfiddle.net/jcward/7hyaC/3/ en op http://jsperf.com/uuid-generator-opt/4

Laten we voor een uitleg beginnen met de code van broofa:

function broofa() {
    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(broofa())

Antwoord 5, autoriteit 7%

Gebruik:

let uniqueId = Date.now().toString(36) + Math.random().toString(36).substring(2);

Antwoord 6, autoriteit 7%

Hier is wat code gebaseerd op RFC 4122, sectie 4.4 (Algoritmen voor het maken van een UUID van echt willekeurig of pseudo-willekeurig getal).

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

Antwoord 7, autoriteit 4%

Dit is de snelste GUID-achtige tekenreeksgeneratormethode in de indeling XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. Het genereert geen standaard-compatibele GUID.

Tien miljoen uitvoeringen van deze implementatie duren slechts 32,5 seconden, wat de snelste is die ik ooit in een browser heb gezien (de enige oplossing zonder lussen/iteraties).

De functie is zo simpel als:

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

Om de prestaties te testen, kunt u deze code uitvoeren:

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

Ik weet zeker dat de meesten van jullie zullen begrijpen wat ik daar heb gedaan, maar misschien is er tenminste één persoon die uitleg nodig heeft:

Het algoritme:

  • De functie Math.random() retourneert een decimaal getal tussen 0 en 1 met 16 cijfers achter de decimale breukpunt (voor
    voorbeeld 0.4363923368509859).
  • Vervolgens nemen we dit getal en converteren
    het naar een string met grondtal 16 (uit het bovenstaande voorbeeld krijgen we
    0.6fb7687f).
    Math.random().toString(16).
  • Vervolgens knippen we het voorvoegsel 0. (0.6fb7687f =>
    6fb7687f) en krijg een string met acht hexadecimale
    karakters lang.
    (Math.random().toString(16).substr(2,8).
  • Soms keert de functie Math.random() terug
    korter nummer (bijvoorbeeld 0.4363), vanwege nullen aan het einde (van het bovenstaande voorbeeld is het nummer eigenlijk 0.4363000000000000). Dat is waarom ik aan deze string "000000000" (een string met negen nullen) toevoeg en deze vervolgens afsnijd met de functie substr() om er precies negen tekens van te maken ( nullen naar rechts invullen).
  • De reden voor het toevoegen van precies negen nullen is vanwege het worstcasescenario, dat is wanneer de functie Math.random() exact 0 of 1 teruggeeft (waarschijnlijkheid van 1/10^16 voor elk van hen). Daarom moesten we er negen nullen aan toevoegen ("0"+"000000000" of "1"+"000000000"), en het vervolgens afsnijden van de tweede index (derde teken) met een lengte van acht tekens. Voor de rest van de gevallen zal de toevoeging van nullen het resultaat niet schaden omdat het het toch afsnijdt.
    Math.random().toString(16)+"000000000").substr(2,8).

De vergadering:

  • De GUID heeft de volgende indeling XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • Ik heb de GUID in vier stukken verdeeld, elk in twee typen (of formaten): XXXXXXXX en -XXXX-XXXX.
  • Nu bouw ik de GUID met behulp van deze twee typen om de GUID samen te stellen met vier stukken, als volgt: XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX.
  • Om te verschillen tussen deze twee typen, heb ik een vlagparameter toegevoegd aan een functie voor het maken van een paar _p8(s), de parameter s vertelt de functie of er streepjes of niet.
  • Uiteindelijk bouwen we de GUID met de volgende keten: _p8() + _p8(true) + _p8(true) + _p8(), en retourneren deze.

Link naar dit bericht op mijn blog

Veel plezier! 🙂


Antwoord 8, autoriteit 3%

Hier is een totaal niet-conforme maar zeer performante implementatie om een ​​ASCII-veilige GUID-achtige unieke identifier te genereren.

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

Genereert 26 [a-z0-9] tekens, wat een UID oplevert die zowel korter als unieker is dan RFC-compatibele GUID’s. Streepjes kunnen triviaal worden toegevoegd als leesbaarheid voor mensen belangrijk is.

Hier zijn gebruiksvoorbeelden en timings voor deze functie en verschillende andere antwoorden op deze vraag. De timing werd uitgevoerd onder Chrome m25, elk 10 miljoen iteraties.

>>> 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 is de timingcode.

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

Antwoord 9, autoriteit 3%

Hier is een combinatie van het meest gestemde antwoord, met een tijdelijke oplossing voor Chrome-botsingen:

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

Het is op jsbin als je het wilt testen.


Antwoord 10, autoriteit 3%

Van de technische blog van 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;
}

Er zijn andere methoden waarbij een ActiveX-besturingselement wordt gebruikt, maar blijf hier uit de buurt!

Ik dacht dat het de moeite waard was erop te wijzen dat geen enkele GUID-generator unieke sleutels kan garanderen (bekijk het Wikipedia-artikel). Er is altijd een kans op aanrijdingen. Een GUID biedt eenvoudigweg een groot genoeg universum aan sleutels om de kans op botsingen tot bijna nul te reduceren.


Antwoord 11, autoriteit 2%

Hier is een oplossing van 9 oktober 2011 uit een opmerking van gebruiker jed op 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)}

Hiermee wordt hetzelfde doel bereikt als de huidige hoogste -rated antwoord, maar in 50+ minder bytes door gebruik te maken van dwang, recursie en exponentiële notatie. Voor degenen die nieuwsgierig zijn hoe het werkt, hier is de geannoteerde vorm van een oudere versie van de functie:

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

Antwoord 12, autoriteit 2%

Je kunt node-uuid gebruiken. Het biedt een eenvoudige, snelle generatie van RFC4122 UUIDS.

Kenmerken:

  • Genereer RFC4122 versie 1 of versie 4 UUID’s
  • Wordt uitgevoerd in Node.js en browsers.
  • Cryptografisch sterke willekeurige # generatie op ondersteunende platforms.
  • Kleine voetafdruk (Wil je iets kleiners? Bekijk dit!)

Installeren met NPM:

npm install uuid

Of gebruik uuid via een browser:

Raw-bestand downloaden (uuid v1): https://raw .githubusercontent.com/kelektiv/node-uuid/master/v1.js
Download Raw-bestand (uuid v4): https://raw.githubusercontent. com/kelektiv/node-uuid/master/v4.js


Wil je nog kleiner? Bekijk dit eens: https://gist.github.com/jed/982883


Gebruik:

// 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'

ECMAScript 2015 (ES6):

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

Antwoord 13

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

Deze versie is gebaseerd op het antwoord van Briguy37 en enkele bitsgewijze operatoren om vensters ter grootte van een knabbel uit de buffer te extraheren.

Het zou moeten voldoen aan het RFC Type 4 (willekeurige) schema, aangezien ik de laatste keer problemen had bij het parseren van niet-compatibele UUID’s met Java’s UUID.


Antwoord 14

Hiermee wordt een UUID van versie 4 gemaakt (gemaakt van pseudo-willekeurige getallen):

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 is een voorbeeld van de gegenereerde UUID’s:

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

Antwoord 15

Eenvoudige JavaScript-module als een combinatie van de beste antwoorden op deze vraag.

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

Antwoord 16

De onderstaande versie is een bewerking van broofa’s antwoord , maar bijgewerkt met een “echte” willekeurige functie die cryptobibliotheken gebruikt waar beschikbaar, en de Alea()-functie als een 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 https://web.archive.org/web/20120502223108/http://baagoe.com/en/RandomMusings/javascript/
      // Johannes Baagoe <[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 BaagA?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);
  });
};

Antwoord 17

JavaScript-project op GitHub – https://github.com/LiosK/UUID.js

UUID.js De RFC-compatibele UUID-generator voor JavaScript.

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

Functies Genereert RFC 4122-compatibele UUID’s.

Versie 4 UUID’s (UUID’s van willekeurige getallen) en versie 1 UUID’s
(tijdgebaseerde UUID’s) zijn beschikbaar.

UUID-object biedt verschillende toegangen tot de UUID, inclusief toegang tot
de UUID-velden.

Lage tijdstempelresolutie van JavaScript wordt gecompenseerd door willekeurig
nummers.


Antwoord 18

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

Antwoord 19

Voor degenen die een RFC 4122 versie 4 compatibele oplossing willen met snelheidsoverwegingen (enkele aanroepen naar Math.random()):

var rand = Math.random;
function UUID() {
    var nbr, randStr = "";
    do {
        randStr += (nbr = rand()).toString(16).substr(3, 6);
    } 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)
    );
}
console.log( UUID() );

Antwoord 20

Ik wilde broofa’s antwoord begrijpen, dus ik breidde het uit en voegde opmerkingen toe:

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

Antwoord 21

Ik heb mijn eigen UUID/GUID-generator aangepast met wat extra’s hier.

Ik gebruik de volgende Kybos generator voor willekeurige getallen om een ​​beetje meer cryptografisch te zijn geluid.

Hieronder staat mijn script met de Mash- en Kybos-methoden van baagoe.com uitgesloten.

//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 BaagA?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));

Antwoord 22

ES6-voorbeeld

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

Antwoord 23

Als je alleen een willekeurige 128-bits tekenreeks in geen bepaald formaat nodig hebt, kun je het volgende gebruiken:

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

Wat iets teruggeeft als 2350143528-4164020887-938913176-2513998651.


Antwoord 24

De native URL.createObjectURL genereert een UUID. U kunt hiervan profiteren.

function uuid() {
  const url = URL.createObjectURL(new Blob())
  const [id] = url.toString().split('/').reverse()
  URL.revokeObjectURL(url)
  return id
}

Antwoord 25

Gewoon weer een beter leesbare variant met slechts twee mutaties.

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

Antwoord 26

De betere manier:

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,
                  ?              // generate 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
 }

Geminimaliseerd:

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}

Antwoord 27

Als uw omgeving SharePoint is, is er een hulpprogramma genaamd SP.Guid.newGuid (MSDN-link waarmee een nieuwe GUID wordt gemaakt. Deze functie bevindt zich in het bestand sp.init.js. Als u deze functie herschrijft (om enkele andere afhankelijkheden van andere privéfuncties), en het ziet er als volgt uit:

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

Antwoord 28

Deze is gebaseerd op datum en voegt een willekeurig achtervoegsel toe om de uniciteit te “verzekeren”.

Het werkt goed voor CSS-ID’s, geeft altijd iets terug als, en is gemakkelijk te 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;
        };

Antwoord 29

Het volgende is eenvoudige code die crypto.getRandomValues(a) gebruikt op ondersteund browsers (Internet Explorer 11+, iOS 7+, Firefox 21+, Chrome en Android Chrome).

Het vermijdt het gebruik van Math.random(), omdat dat botsingen kan veroorzaken (bijvoorbeeld 20 botsingen voor 4000 gegenereerde UUID’s in een echte situatie door Muxa).

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

Opmerkingen:

  • Geoptimaliseerd voor leesbaarheid van de code, niet voor snelheid, dus geschikt voor bijvoorbeeld een paar honderd UUID’s per seconde. Het genereert ongeveer 10000 uuid() per seconde in Chromium op mijn laptop met behulp van http://jsbin.com/fuwigo/1 om prestaties te meten.
  • Het gebruikt alleen 8 voor “y” omdat dat de leesbaarheid van de code vereenvoudigt (y mag 8, 9, zijn A of B).

Antwoord 30

OK, gebruik het pakket uuid en de ondersteuning ervan voor versie 1, 3, 4 en 5 UUID’s, doe:

yarn add uuid

En dan:

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

Je kunt het ook doen met volledig gespecificeerde opties:

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'

Ga voor meer informatie naar de npm-pagina hier.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4 × 3 =

Other episodes