it-swarm-eu.dev

Vytvořit GUID / UUID v JavaScriptu?

V JavaScriptu se snažím vytvářet globálně jedinečné identifikátory. Nejsem si jistý, jaké rutiny jsou k dispozici ve všech prohlížečích, jak "náhodný" a nasazený vestavěný generátor náhodných čísel je, atd.

GUID/UUID by mělo být nejméně 32 znaků a mělo by zůstat v rozsahu ASCII, aby se předešlo problémům při jejich předávání.

3519
Jason Cohen

UUID (Universally Unique IDentifier), také známý jako GUID (Globally Unique IDentifier), jsou podle RFC 4122 , identifikátory s jistou jistotou.

Nejlepším způsobem, jak je vygenerovat, je dodržovat instrukce k implementaci v uvedené RFC, použít jednu z mnoha komunitně ověřených implementací open source, nebo pro jazyky, které ji mají, použít vestavěnou implementaci.

Některé příklady open source nástrojů pro práci s UUIDs, pro některé populární programovací jazyky jsou vypsány tady.

JavaScript

PHP

Jít

Ruby

Python


Všimněte si, že právě náhodně generování identifikátorů bajtů po bajtech nebo znak po znaku vám nedává stejné záruky jako vyhovující implementace. Velmi důležité je také to, že systémy pracující s kompatibilními UUID se mohou rozhodnout nepřijímat náhodně generované systémy a mnoho validátorů s otevřeným zdrojovým kódem skutečně zkontroluje platnou strukturu.

UUID musí mít tento formát:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Kde pozice M a N mohou mít pouze určité hodnoty. V tuto chvíli jsou jediné platné hodnoty pro M 1, 2, 3, 4 a 5, takže náhodně generování této pozice by učinilo většinu výsledků nepřijatelnými.

2098
John Millikin

Pro řešení kompatibilní s RFC4122 version 4 je toto řešení s jedním linerem (ish) nejkompaktnější, jaké jsem mohl přijít.

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: Uvědomte si, že jedinečnost UUID závisí na základním generátoru náhodných čísel (RNG). Řešení výše používá Math.random() pro stručnost, nicméně Math.random() je ne zaručeno, že bude vysoce kvalitní RNG. Podrobnosti naleznete v článku Adam Hyland vynikající zápis na Math.random () . Pro více robustní řešení, zvažte něco jako uuid modul [Disclaimer: Jsem autor], který používá vyšší kvalitu RNG API, pokud jsou k dispozici.

Update, 2015-08-26: Jako vedlejší poznámka tento Gist popisuje, jak určit, kolik ID může být generováno před dosažením určité pravděpodobnosti kolize. Například, s 3.26x1015 verze 4 RFC4122 UUIDs máte šanci na kolizi 1 v milionu.

Update, 2017-06-28: A dobrý článek od vývojářů Chrome diskutující o stavu Math.random PRNG v Chrome, Firefoxu a Safari. tl; dr - Od konce roku 2015 je to „docela dobré“, ale ne kryptografická kvalita. Chcete-li řešit tento problém, zde je aktualizovaná verze výše uvedeného řešení, které používá ES6, crypto API, a trochu JS wizardy, za které nemohu přijmout kredit :

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

Opravdu se mi líbí, jak je čistá Broofova odpověď je, ale je to nešťastné, že špatné implementace Math.random nechávají šanci na kolizi. 

Zde je podobné RFC4122 verze 4 kompatibilní řešení, které řeší tento problém kompenzací prvních 13 hexadecimálních čísel hexadecimální částí časové značky. Tímto způsobem, i když je Math.random na stejném semeni, museli by oba klienti generovat UUID v přesně stejné milisekundě (nebo o 10 000+ let později), aby získali stejné UUID: 

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


Tady je housle k testování.

726
Briguy37

broofa odpověď je docela úhledný, opravdu - působivě chytrý, opravdu ... rfc4122 kompatibilní, poněkud čitelné a kompaktní. Úžasný!

Pokud se ale díváte na tento regulární výraz, mnoho volání replace(), toString() a Math.random() volání funkcí (kde používá pouze 4 bity výsledku a ztrácí zbytek), můžete začít uvažovat o výkonu. Opravdu, joelpt dokonce rozhodl se vyhodit RFC pro generickou GUID rychlost s generateQuickGUID.

Ale můžeme získat rychlost a RFC dodržování? Říkám ano! Můžeme zachovat čitelnost? No ... Ne, ale je to snadné, pokud budete následovat.

Nejdříve ale moje výsledky, ve srovnání s broofou, guid (přijatá odpověď), a non-rfc-kompatibilní 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.

Takže díky mé šesté iteraci optimalizací jsem porazil nejoblíbenější odpověď nad 12X, přijatou odpovědí over 9X a rychlou odpovědí 2-3X. A já jsem stále rfc4122 kompatibilní.

Zajímá vás, jak? Celý zdroj jsem dal na http://jsfiddle.net/jcward/7hyaC/3/ a na http://jsperf.com/uuid-generator-opt/4

Pro vysvětlení začněme s broofovým kódem:

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

Nahradí tedy x libovolnou náhodnou hexadecimální číslicí y náhodnými daty (kromě vynucení horních 2 bitů na 10 podle specifikace RFC) a regex neodpovídá znakům - nebo 4 znaků, takže se nemusí zabývat s nimi. Velmi, velmi kluzký.

První věc, kterou byste měli vědět, je to, že volání funkcí jsou drahá, stejně jako regulární výrazy (i když používá pouze 1, má 32 zpětných volání, jedno pro každý zápas a v každém z 32 zpětných volání nazývá Math.random () a v. toString (16)).

Prvním krokem směrem k výkonu je odstranění funkce RegEx a jejích funkcí zpětného volání a místo toho použití jednoduché smyčky. To znamená, že se musíme zabývat znaky - a 4, zatímco broofa ne. Všimněte si také, že můžeme použít indexování String Array, abychom zachovali jeho úhlednou architekturu šablony String:

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

V podstatě stejná vnitřní logika, s výjimkou kontroly - nebo 4, a použití smyčky while (namísto zpětných volání replace()) nám dává téměř 3násobné zlepšení!

Další krok je malý na ploše, ale dělá slušný rozdíl v mobilu. Udělejme méně Math.random () volání a využití všech těchto náhodných bitů namísto házení 87% z nich s náhodné buffer, který dostane posunul z každé iterace. Pojďme také přesunout definici šablony ze smyčky, jen v případě, že to pomůže:

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
}

To nám ušetří 10-30% v závislosti na platformě. Není špatné. Další velký krok se však zbaví volání funkce toString spolu s optimalizační klasikou - vyhledávací tabulkou. Jednoduchá vyhledávací tabulka s 16 prvky provede úlohu toString (16) v mnohem kratším čase:

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
}

Další optimalizací je další klasika. Protože v každé iteraci smyčky zpracováváme pouze 4-bitové výstupy, snižme počet smyček na polovinu a každou iteraci zpracuje 8 bitů. To je ošidné, protože stále musíme zvládnout bitové pozice kompatibilní s RFC, ale není to příliš těžké. Pak musíme udělat větší vyhledávací tabulku (16x16 nebo 256) pro uložení 0x00 - 0xff a my ji budujeme pouze jednou, mimo funkci 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
}

Snažil jsem se o e6 (), který zpracovává 16 bitů najednou, stále s použitím 256-LUT LUT, a to ukázalo klesající návratnost optimalizace. Ačkoli to mělo méně iterací, vnitřní logika byla komplikovaná zvýšeným zpracováním, a to dělalo to stejné na ploše, a jediný ~ 10% rychlejší na mobilu.

Konečná technika optimalizace, která se má použít - rozviňte smyčku. Vzhledem k tomu, že opakujeme několikrát, můžeme to technicky napsat ručně. Snažil jsem se to jednou s jednou náhodnou proměnnou r, že jsem stále re-přiřazení, a výkon tanked. Ale se čtyřmi proměnnými přiřazenými náhodnými daty dopředu, pak pomocí vyhledávací tabulky a použitím správných bitů RFC, tato verze je všechny smačí:

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

Modulární: http://jcward.com/UUID.js - UUID.generate()

Legrační věc je, že 16 bajtů náhodných dat je snadná část. Celý trik je vyjádřen ve formátu String s RFC shodou, a je to nejpřísněji provedeno s 16 bajty náhodných dat, rozvinutou smyčkou a vyhledávací tabulkou.

Doufám, že moje logika je správná - je velmi snadné udělat chybu v tomto druhu nudné práce. Ale výstupy vypadají dobře. Doufám, že jste si tuto šílenou jízdu užili díky optimalizaci kódu!

Doporučuji: mým hlavním cílem bylo ukázat a naučit potenciální strategie optimalizace. Další odpovědi pokrývají důležitá témata, jako jsou kolize a skutečně náhodná čísla, která jsou důležitá pro generování dobrých UUID.

353
Jeff Ward

Zde je nějaký kód založený na RFC 4122 , část 4.4 (Algoritmy pro vytvoření UUID z opravdu náhodného nebo náhodného čísla).

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

Nejrychlejší GUID jako metoda generátoru řetězců ve formátu XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. To nevytváří standardně kompatibilní GUID.

Deset milionů provedení této implementace zabere jen 32,5 sekundy, což je nejrychlejší, co jsem kdy viděl v prohlížeči (jediné řešení bez smyček/iterací).

Funkce je stejně jednoduchá jako:

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

Chcete-li otestovat výkon, můžete tento kód spustit:

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

Jsem si jist, že většina z vás pochopí, co jsem tam udělal, ale možná je alespoň jedna osoba, která bude potřebovat vysvětlení:

Algoritmus:

  • Funkce Math.random() vrátí desetinné číslo mezi 0 a 1 s 16 číslicemi po desetinném zlomku bodu (pro Příklad 0.4363923368509859).
  • Pak vezmeme toto číslo a převedeme jej na řetězec se základnou 16 (z výše uvedeného příkladu 0.6fb7687f).
    Math.random().toString(16).
  • Pak odřízneme předponu 0. (0.6fb7687f => 6fb7687f) a získáte řetězec s osmi hexadecimálními Znaky.
    (Math.random().toString(16).substr(2,8).
  • Někdy funkce Math.random() vrátí Kratší číslo (například 0.4363), kvůli nule na konci (z výše uvedeného příkladu, ve skutečnosti je číslo 0.4363000000000000). Proto připojuji k tomuto řetězci "000000000" (řetězec s devíti nulami) a pak jej rozřezávám funkcí substr(), aby bylo přesně 9 znaků (vyplnění nul napravo).
  • Důvodem pro přidání přesně devíti nul je scénář horšího případu, kdy funkce Math.random() vrátí přesně 0 nebo 1 (pravděpodobnost 1/10 ^ 16 pro každou z nich). Proto jsme k ní potřebovali přidat devět nul ("0"+"000000000" nebo "1"+"000000000") a pak je odříznout od druhého indexu (3. znak) o délce osmi znaků. Pro zbytek případů, přidání nul nebude poškodit výsledek, protože to je řez to stejně.
    Math.random().toString(16)+"000000000").substr(2,8).

Shromáždění:

  • GUID je v následujícím formátu XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • GUID jsem rozdělil na 4 kusy, každý kus rozdělen do 2 typů (nebo formátů): XXXXXXXX a -XXXX-XXXX.
  • Teď buduji GUID pomocí těchto 2 typů, abych sestavil GUID s voláním 4 kusy takto: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • Chcete-li se lišit mezi těmito dvěma typy, přidal jsem parametr příznaku do funkce párového tvůrce _p8(s), parametr s říká funkci, zda má přidat pomlčky nebo ne.
  • Nakonec postavíme GUID s následujícím řetězením: _p8() + _p8(true) + _p8(true) + _p8() a vrátíme jej.

Odkaz na tento příspěvek na mém blogu

Užívat si! :-)

82
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>

Pokud jsou ID generovány více než 1 milisekundu, jsou 100% jedinečné.

Pokud jsou dva ID generovány v kratších intervalech, a za předpokladu, že náhodná metoda je skutečně náhodná, bude to generovat ID, která jsou 99,99999999999999% pravděpodobně globálně jedinečná (kolize v 1 z 10 ^ 15)

Toto číslo můžete zvýšit přidáním dalších číslic, ale pro generování 100% jedinečných ID budete muset použít globální čítač.

pokud opravdu potřebujete splnění RFC, toto formátování projde jako platná verze 4 GUID:

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: Výše ​​uvedený kód následuje záměr, ale ne dopis RFC. Mimo jiné je to několik náhodných číslic krátkých. (Pokud to potřebujete, přidejte více náhodných číslic) Vzhůru je, že je to opravdu rychlé, ve srovnání se 100% kompatibilním kódem. Zde můžete otestovat své GUID zde

81
Simon Rigét

Zde je kombinace top hlasované odpovědi , s řešením kolizí Chrome :

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

Zapnuto jsbin pokud ho chcete otestovat.

60
ripper234

Zde je řešení ze dne 9. října 2011 z komentáře uživatele jed na 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)}

To dosahuje stejného cíle jako současná nejvýše hodnocená odpověď , ale v 50 + méně bytech využíváním donucování, rekurze a exponenciálního zápisu. Pro ty zvědavé, jak to funguje, zde je anotovaná forma starší verze funkce:

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

Zde je naprosto nekompatibilní, ale velmi výkonná implementace, která generuje jednoznačný identifikátor GUID podobný ASCII.

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

Generuje 26 znaků [a-z0-9], což dává UID, který je kratší a více jedinečný než GUID kompatibilní s RFC. Pokud se jedná o čitelnost člověka, mohou být pomazány triviálně.

Zde jsou příklady použití a načasování této funkce a několik dalších odpovědí této otázky. Načasování bylo provedeno v Chrome M25, 10 milionů iterací.

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

Zde je časovací kód.

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

Můžete použít node-uuid ( https://github.com/kelektiv/node-uuid )

Jednoduchá, rychlá generace RFC4122 UUIDS.

Funkce:

  • Generovat UUID RFC4122 verze 1 nebo verze 4
  • Běží v node.js a prohlížečích.
  • Kryptograficky silná náhodná generace na podpůrných platformách.
  • Malá stopa (Chcete něco menšího? Zkontrolujte toto! )

Instalace pomocí NPM:

npm install uuid

Nebo Použití uuid přes prohlížeč:

Stáhnout soubor Raw (uuid v1): https://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.js Stáhnout soubor Raw (uuid v4): https: //raw.githubusercontent.com/kelektiv/node-uuid/master/v4.js


Chcete ještě menší? Podívejte se na: https://Gist.github.com/jed/982883


Použití:

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

Od technický blog 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;
}

Existují jiné metody, které zahrnují použití ovládacího prvku ActiveX, ale drž se dál od těchto!

Edit: Myslel jsem, že stojí za to poukázat na to, že žádný GUID generátor nemůže zaručit jedinečné klíče (zkontrolujte článek wikipedia ). Vždy existuje možnost kolizí. GUID jednoduše nabízí dostatečně velký vesmír klíčů ke snížení změny kolizí na téměř nulu.

31
Prestaul

Webová služba by byla užitečná. 

Rychlé vyhledávání Google: http://www.hoskinson.net/GuidGenerator/

Nelze ručit za tuto implementaci, ale SONEONE musí zveřejnit generátor bonafide GUID.

S takovou webovou službou můžete vytvořit webové rozhraní REST, které spotřebovává webovou službu GUID, a prostřednictvím prohlížeče AJAX slouží k zobrazení JavaScriptu v prohlížeči.

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

UPRAVIT:

Znovu zkontroloval můj projekt, který používal tuto funkci a nelíbil se výřečnosti. - Ale potřeboval pořádnou náhodnost.

Verze založená na odpovědi od Briguy37 a několik bitových operátorů, kteří mají extrahovat z vyrovnávací paměti okna s velkými okny.

Měli by dodržovat RFC Type 4 (náhodné) schéma, protože jsem naposledy měl problémy s analýzou nekompatibilních uuids s UUID jazyka Java.

29
sleeplessnerd

Jednoduchý JavaScript modul jako kombinace nejlepších odpovědí v tomto vlákně.

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

Používání: 

Guid.newGuid ()

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

Guid.empty

"00000000-0000-0000-0000-000000000000"

28
kayz1

Od dobré ol 'wikipedia tam je odkaz na implementaci javascriptu UUID.

Vypadá to docela elegantní a možná by ho bylo možné vylepšit nasolením IP adresy klienta. Tento hash by mohl být vložen do html dokumentu na straně serveru pro použití javascriptem na straně klienta.

UPDATE: Původní web měl shuffle, zde je aktualizovaná verze

23
Dan

To už má spoustu odpovědí, ale bohužel v partě není "pravá" náhoda. Níže uvedená verze je adaptací odpovědí broofy, ale aktualizována tak, aby zahrnovala "pravou" náhodnou funkci, která používá kryptografické knihovny tam, kde jsou k dispozici, a funkce Alea () jako nouzový.

  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

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

UUID.js Generátor UUID kompatibilní s RFC pro JavaScript.

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

Funkce Generuje RU 4122 kompatibilní UUID.

K dispozici jsou verze 4 UUID (UUID z náhodných čísel) a UUID verze 1. (UUID založené na čase).

Objekt UUID umožňuje různý přístup k UUID včetně přístupu k polím UUID.

Nízké časové rozlišení JavaScriptu je kompenzováno náhodnými Čísly.

21

Tím vytvoříte UUID verze 4 (vytvořené z pseudonáhodných čísel):

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

Zde je ukázka vygenerovaných identifikátorů UUID:

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

Upravený vlastní UUID/GUID generátor s některými doplňky zde .

Používám následující generátor Kybos náhodné číslo, abych byl o něco více kryptograficky slyšet.

Níže je můj skript s metodami Mash a Kybos z baagoe.com vyloučen.

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

Lepší způsob:

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
 }

Minimalizováno:

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

Chtěl jsem pochopit odpověď broofy, takže jsem ji rozšířil a přidal komentáře:

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

Vzorek ES6

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

Je to jen jednoduché volání AJAX ...

Jestli má někdo zájem, tady je moje řešení.

Na straně serveru:

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

Na straně klienta:

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

Pro ty, kteří potřebují řešení vyhovující standardu rfc4122 verze 4 s ohledem na rychlost (několik volání do 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("");
}

Výše uvedená funkce by měla mít slušnou rovnováhu mezi rychlostí a náhodností.

11
John Fowler

Je zde plugin jQuery, který zpracovává Guid's @ http://plugins.jquery.com/project/GUID_Helper

jQuery.Guid.Value()

Vrátí hodnotu interního Guid. Pokud není zadán žádný pokyn, vrací nový (hodnota je pak uložena interně).


jQuery.Guid.New()

Vrátí nový Guid a nastaví jeho hodnotu interně.


jQuery.Guid.Empty()

Vrátí prázdnou Guid 00000000-0000-0000-0000-000000000000.


jQuery.Guid.IsEmpty()

Vrací boolean. True, pokud je prázdný/undefined/blank/null.


jQuery.Guid.IsValid()

Vrací boolean. Pravdivá platná směrnice, falešná, ne-li.


jQuery.Guid.Set()

Retrns Guid. Nastaví Guid na zadaného Guid uživatele, pokud je neplatný, vrátí prázdnou vodítko.

10
Levitikon

Vím, je to stará otázka. Jen pro úplnost, pokud je vaše prostředí SharePoint, je zde funkce utility nazvaná SP.Guid.newGuid ( msdn link ), která vytvoří nový guid. Tato funkce je uvnitř souboru sp.init.js. Pokud tuto funkci přepíšete (chcete-li odstranit jiné závislosti od jiných soukromých funkcí), vypadá to takto:

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

Ten je založen na datu a přidává náhodnou příponu, aby "zajistil" jedinečnost. Funguje dobře pro identifikátory css. Vždy vrací něco podobného a je snadné ho zaseknout:

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

Jednoduchý kód, který používá crypto.getRandomValues(a) na podporovaných prohlížečích (IE11 +, iOS7 +, FF21 +, Chrome, Android Chrome). Vyhýbá se použití Math.random(), protože to může způsobit kolize (například 20 kolizí pro 4000 generovaných uuids v reálné situaci pomocí 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);
}

Poznámky:

  • Optimalizováno pro čitelnost kódu není rychlost, takže je vhodné říci pár set uuid za sekundu. Generuje přibližně 10000 uuid () za sekundu v Chromu na svém notebooku pomocí http://jsbin.com/fuwigo/1 k měření výkonu.
  • Používá pouze 8 pro "y", protože to zjednodušuje čitelnost kódu (y je povoleno být 8, 9, A nebo B).
6
robocat

Pokud potřebujete náhodný 128bitový řetězec v žádném konkrétním formátu, můžete použít:

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

Což vrátí něco jako 2350143528-4164020887-938913176-2513998651.

6
Jonathan Potter

Je důležité používat dobře testovaný kód, který je spravován více než 1 přispěvateli místo toho, abyste si na to šlehali vlastní věci. Toto je jedno z míst, kde budete pravděpodobně chtít preferovat nejstabilnější kód, než je nejkratší možná chytrá verze, která funguje v prohlížeči X, ale nebere v úvahu idiosynkrázie Y, které by často vedly k velmi těžkým vyšetřením chyb, než se projeví pouze náhodně pro některé uživatele. Osobně používám uuid-js na https://github.com/aurigadl/uuid-js který bower povolil, takže můžu provádět aktualizace snadno.

5
Shital Shah

Jen další čitelnější varianta s pouhými dvěma mutacemi.

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

Používám tuto funkci níže, doufám, že to může být užitečné.

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

Můžete použít balíček npm guid, generátor guid a validátor.

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

Příklad:

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

UPDATE: Tento balíček byl zastaralý. Místo toho použijte uuid

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

Příklad: 

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

Jen pro případ, že by někdo, kdo by sháněl google, hledal malou knihovnu, ShortId ( https://www.npmjs.com/package/shortid ) splňuje všechny požadavky této otázky. Umožňuje specifikovat povolené znaky a délku a garantuje nesekvenční, neopakující se řetězce.

Aby to bylo více skutečnou odpovědí, jádro této knihovny používá k vytvoření svých krátkých id následující logiku:

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

Nezpracoval jsem to, aby odrážel pouze nejzákladnější části tohoto přístupu, takže výše uvedený kód obsahuje nějakou další logiku z knihovny. Pokud jste zvědaví na všechno, co dělá, podívejte se na zdroj: https://github.com/dylang/shortid/tree/master/lib

3
MaxPRafferty

Tento skript je užitečný pro vytváření identifikátorů GUID v JavaScriptu

https://github.com/addui/GUIDJS

var myGuid = GUID();
3
Dustin Poissant

Pro ty, kteří používají Javascript ve Windows (např. WScript/CScript/MSHTA). Lze použít ActiveX. Konkrétně objekt Scriptlet.Typelib:

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

Všimněte si, že tato odpověď funguje pouze na technologiích, které jsem uvedl, nebude fungovat žádný prohlížeč, ani Microsoft Edge! Tedy, váš kilometr se bude lišit s touto odpovědí.

2
Stephen Quan

Pro můj případ použití jsem požadoval generování id, které bylo zaručeno, že bude celosvětově jedinečné; bez výjimky. Chvíli jsem s problémem bojoval a přišel s řešením zvaným tuid (Truly Unique ID). Generuje id s prvními 32 znaky, které jsou generovány systémem, a zbývající číslice představují milisekundy od doby Epoch. V situacích, kdy potřebuji generovat id na JavaScriptu na straně klienta, to funguje dobře. Podívej se:

https://github.com/mongoh/tuid

2
Rishi

Ahoj tady je funkční příklad, který generuje 32místné UUID. 

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

Nemohl jsem najít žádnou odpověď, která používá jeden 16-oktet TypedArray a DataView, takže si myslím, že následující řešení pro generování verze 4 UUID za RFC bude stát na tomto místě zde:

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
}

Dávám přednost, protože se spoléhá pouze na funkce dostupné pro standardní platformu ECMAScript.

1
amn

na základě práce broofa jsem přidal další náhodnost přidáním časové značky do matematiky. 

Doufám, že to pomůže

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

Zde najdete velmi malou funkci, která generuje uuids https://Gist.github.com/jed/982883

Jednou z finálních verzí je:

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

Jednoduchým řešením pro generování jedinečné identifikace je použít token času a přidat k němu náhodné číslo. Dávám přednost předponu s "uuid-".

Níže uvedená funkce vygeneruje náhodný řetězec typu: uuid-14d93eb1b9b4533e6 . Člověk nemusí vytvářet náhodný řetězec 32 znaků. 16 char náhodný řetězec je více než dostačující v tomto případě poskytnout jedinečné UUID v javascriptu.

 var createUUID = function () {
 return "uuid -" + ((nový Date) .getTime (). toString (16) + Math.floor (1E7 * Math.random ()) .toString (16)); 
} 
0
mangalbhaskar

OK, pomocí balíku uuid, podpora pro verze 1, 3, 4 a 5 UUID do:

yarn add uuid

a pak:

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

Můžete to také provést s plně zadanými možnostmi:

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'

Pro více informací navštivte stránku npm zde

0
Alireza

Jen jsem si myslel, že bych udělal další způsob, jak udělat totéž.

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

To může být pro někoho užitečné ...

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

Můžeme použít náhradní a crypto.getRandomValues ​​k získání podobného výstupu:

xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx

 enter image description here

Pokud hledáme řešení opti, musíme nahradit crypto.getRandomValues(new Uint8Array(1))[0] maticí (32).

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

Chcete-li získat tento kód:

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

Srážka:

Můžeme udělat něco jako Google Analytics a přidat časové razítko s: uuidv4() + "." + (+new Date()).

0
A-312

Pro vědu. Neviděl jsem nikoho, kdo by to dělal ... není v4 kompatibilní, ale mohl by být snadno změněn tak, aby byl. Je to jen příklad rozšíření Uint8Array type a pomocí crypto.getRandomValues ​​() pro generování hodnot uuid bajtů.

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