it-swarm-tr.com

Yaratmak GUID / UUID JavaScript’te?

JavaScript'te global olarak benzersiz tanımlayıcılar oluşturmaya çalışıyorum. Tüm tarayıcılarda hangi rutinlerin mevcut olduğundan, dahili rasgele sayı üretecinin "rasgele" olarak nasıl sıralandığından emin değilim.

GUID/UUID en az 32 karakterden oluşmalı ve etrafta dolaşırken sorun yaşanmaması için ASCII aralığında kalmalıdır.

3519
Jason Cohen

RFC 4122 uyarınca, GUID (Globally Unique IDentifier) ​​olarak da bilinen UUID'ler (Evrensel Benzersiz Tanımlayıcı), belirli bir benzersizlik garantisi olan tanımlayıcılardır.

Bunları oluşturmanın en iyi yolu, söz konusu RFC'deki uygulama talimatlarını takip etmek, çok sayıda topluluğun açık kaynak kodlu uygulamalarından birini kullanmak veya sahip olduğu diller için yerleşik uygulamayı kullanmaktır.

Bazı popüler programlama dilleri için UUID'lerle çalışmak için bazı açık kaynaklı araçlar burada listelenmiştir.

JavaScript

PHP

Git

Ruby

Python


Tanımlayıcıları bayt by by veya karakter karakter olarak rastgele oluşturmanın size uygun bir uygulama ile aynı garantileri vermeyeceğini unutmayın. Ayrıca, çok önemli, uyumlu UUID'lerle çalışan sistemler rastgele oluşturulmuş olanları kabul etmemeyi seçebilir ve birçok açık kaynak onaylayıcısı aslında geçerli bir yapı olup olmadığını kontrol eder.

Bir UUID bu formata sahip olmalıdır:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

M ve N konumlarının yalnızca belirli değerleri olabilir. Şu anda, M için geçerli olan tek değerler 1, 2, 3, 4 ve 5'tir, bu nedenle bu pozisyonu rastgele oluşturmak çoğu sonucu kabul edilemez hale getirir.

2098
John Millikin

Bir RFC4122 sürüm 4 uyumlu çözüm için, bu tek astarlı (ish) çözüm bulabildiğim en kompakt çözümdür:

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

Güncelleme, 2015-06-02 : UUID benzersizliğinin, altta yatan rasgele sayı üretecine (RNG) büyük ölçüde bağlı olduğunu unutmayın. Yukarıdaki çözüm, kısaltma için Math.random() kullanır, ancak Math.random(), yüksek kaliteli bir RNG olacağı garanti edilmez. Daha fazla bilgi için Adam Hyland'ın Math.random () adresindeki mükemmel yazım hatası) =/bölümüne bakın. Daha sağlam bir çözüm için, id modülü [Feragatname: Ben yazarım], yüksek kaliteli RNG API'leri kullanan bir şey gibi düşünün) mümkün olduğunda.

Güncelleme, 2015-08-26 : Bir not olarak, bu Gist , ulaşmadan önce kaç tane kimlik oluşturulabileceğini nasıl belirleyeceğini açıklar. Belli bir çarpışma olasılığı, örneğin, 3.26x1015 sürüm 4 RFC4122 UUID'ler milyonda bir çarpışma şansına sahipler.

Güncelleme, 2017-06-28 : A Chrome geliştiricisinden iyi makale Math.random durumunu tartışıyor _)PRNG Chrome, Firefox ve Safari’de _ kalite tl; dr - 2015 yılının sonlarından itibaren "oldukça iyi", ancak şifreleme kalitesi değil. Bu konuyu ele almak için, yukarıdaki çözümün kullandığı güncellenmiş bir sürüm. ES6, crypto API ve bir miktar JS sihirbazı için kredi alamıyorum :

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

Broofa'nın cevabının cevabını gerçekten çok seviyorum, ama Math.random uygulamalarının zayıf uygulamalarının çarpışma şansını bırakması talihsiz bir durum. 

Benzer bir RFC4122 sürüm 4 uyumlu çözelti, ilk 13 onaltılık sayıyı zaman damgasının onaltılık bir kısmı ile telafi ederek çözüyor. Bu şekilde, Math.random aynı tohumda olsa bile, her iki müşterinin de aynı UUID'yi elde etmek için UUID'yi aynı milisaniyede (veya 10.000+ yıl sonra) oluşturması gerekir: 

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


İşte test edilecek bir keman.

726
Briguy37

broofa'nın cevabı oldukça kaygan, gerçekten - etkileyici şekilde zekice, gerçekten ... rfc4122 uyumlu, biraz okunaklı ve kompakt. Korku veren!

Ancak, bu düzenli ifadeye bakarsanız, bu birçok replace() geri aramaları, toString() 's ve Math.random() işlev çağrıları (sonucun sadece 4 bitini kullandığı ve gerisini boşa harcadığı) bakarsanız, performansı merak etmeye başlayabilirsiniz. Aslında joelpt, GUID hızı için RFC'yi generateQuickGUID ile atmaya bile karar verdi.

Fakat hız ve RFC uyumluluğunu alabilir miyiz? Diyorum, YES! Okunabilirliği koruyabilir miyiz? Şey ... Pek sayılmaz, ama takip etmek kolaydır.

Ancak ilk olarak, sonuçlarım brofafa, guid (kabul edilen cevap) ve rfc uyumlu olmayan generateQuickGuid ile karşılaştırıldığında:

                  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.

Bu yüzden, 6ncı optimizasyon yinelememle, en popüler cevabı 12X , kabul edilen cevabı bitti 9X ve uyumlu olmayan hızlı cevap 2-3X . Ve hala rfc4122 ile uyumluyum.

Nasıl ilgileniyorsunuz? Kaynağın tamamını http://jsfiddle.net/jcward/7hyaC/3/ ve üzeri http://jsperf.com/uuid-generator-opt/4) yazdım.

Bir açıklama için broofa kodu ile başlayalım:

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

Böylece, x ile herhangi bir rasgele onaltılık rakam, y ile rasgele veri (en üstteki 2 bit RFC spec başına 10 'a zorlamak hariç) yerine geçer ve regex - veya 4 karakterleriyle eşleşmez, bu yüzden onlarla uğraşmak zorunda değil. Çok, çok kaygan.

Bilinmesi gereken ilk şey, işlev ifadelerinin normal ifadelerde olduğu gibi pahalı olmasıdır (yalnızca 1 kullanmasına rağmen, her eşleşmede bir tane olmak üzere 32 geri çağırmaya ve 32 geri çağırmanın her birinde Math.random () ve v olarak adlandırılır. toString (16)).

Performansa doğru ilk adım RegEx ve geri çağırma işlevlerini ortadan kaldırmak ve bunun yerine basit bir döngü kullanmaktır. Bunun anlamı, - ve 4 karakterleriyle başa çıkmamız gerektiği anlamına gelir; Ayrıca, kaygan String şablonu mimarisini korumak için String Array dizinini kullanabileceğimize dikkat edin:

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

Temel olarak, aynı iç mantık, - veya 4 olup olmadığını kontrol etmemiz ve bir while döngüsü kullanmamız dışında (replace() callbacks yerine) bize neredeyse 3 kat daha iyi bir gelişme sağlıyor!

Bir sonraki adım, masaüstünde küçük bir adım olmakla birlikte, mobil cihazlarda iyi bir fark yaratır. Şimdi daha az Math.random () çağrısı yapıp, her yinelemeyi değiştiren rastgele bir tamponla% 87'sini atmak yerine tüm bu rastgele bitleri kullanalım. Ayrıca, bu şablon tanımını, sadece yardımcı olması durumunda, döngüden çıkaralım:

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
}

Bu da platforma bağlı olarak% 10-30 tasarruf sağlıyor. Fena değil. Ancak bir sonraki büyük adım, toString işlevinin bir optimizasyon klasiği ile çağrılardan tamamen kurtarılmasıdır - arama tablosu. 16 elemanlı basit bir arama tablosu toString'in (16) işini çok daha kısa sürede gerçekleştirir:

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
}

Bir sonraki optimizasyon başka bir klasik. Her döngü yinelemesinde yalnızca 4 bit çıktı kullandığımızdan, döngü sayısını yarıya indirelim ve her yinelemede 8 bit işleyelim. Bu çok zor, çünkü RFC uyumlu bit konumlarını kullanmak zorundayız, ancak çok da zor değil. Daha sonra 0x00 - 0xff saklamak için daha geniş bir arama tablosu yapmamız gerekiyor (16x16 veya 256) ve e5 () işlevinin dışında sadece bir kez oluşturduk.

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
}

Hala 256 elemanlı LUT kullanarak, bir seferde 16 bit işleyen bir e6 () denedim ve optimizasyonun azalan getirilerini gösterdi. Daha az yineleme olmasına rağmen, iç mantık artan işlemden dolayı karmaşıktı ve aynı şeyi masaüstünde gerçekleştirdi ve mobilde sadece ~% 10 daha hızlı.

Uygulanacak son optimizasyon tekniği - döngüyü kaldırın. Sabit bir sayıda döngü oluşturduğumuzdan, bunu teknik olarak elle yazabiliriz. Bunu bir kez daha atamaya devam ettiğim tek bir rastgele değişken r ile denedim ve performans tanklandı. Ancak dört değişkene önceden rasgele veri atanmış, ardından arama tablosunu kullanarak ve uygun RFC bitlerini uygulayarak, bu sürüm hepsini içiyor:

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

Modüle: http://jcward.com/UUID.js - UUID.generate()

İşin garibi, 16 byte'lık rasgele veri oluşturmak kolay kısmı. Tüm hile RFC uyumu ile String formatında ifade ediyor ve en sık 16 byte rastgele veri, kontrolsüz bir döngü ve arama tablosu ile başarılır.

Umarım mantığım doğrudur - bu tür sıkıcı işlerde hata yapmak çok kolaydır. Fakat çıktılar bana iyi geldi. Umarım kod optimizasyonu ile bu deli sürüş zevk!

Tavsiye edilir: Öncelikli hedefim potansiyel optimizasyon stratejilerini göstermek ve öğretmekti. Diğer cevaplar, iyi UUID'ler oluşturmak için önemli olan çarpışmalar ve gerçekten rastgele sayılar gibi önemli konuları kapsar.

377
Jeff Ward

İşte RFC 4122 , bölüm 4.4 (Gerçekten Rastgele veya Sahte Rastgele Sayıdan bir UUID Oluşturma Algoritmaları) temelli bazı kodlar.

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
let uniqueId = Math.random().toString(36).substring(2) + Date.now().toString(36);
document.getElementById("unique").innerHTML =
  Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
<div id="unique">
</div>

Kimlikler 1 milisaniyeden daha fazla aralıklarla üretiliyorsa,% 100 benzersizdir.

İki ID daha kısa aralıklarla üretilirse ve rastgele yöntemin gerçekten rastgele olduğunu varsayarsak, bu% 99.99999999999999 'un global olarak benzersiz olması muhtemel olan ID'ler üretecektir (10/15'in 1'inde çarpışma).

Daha fazla basamak ekleyerek bu sayıyı artırabilirsiniz, ancak% 100 benzersiz kimlik oluşturmak için genel bir sayaç kullanmanız gerekir.

rFC uyumluluğu gerekiyorsa, bu biçimlendirme geçerli bir sürüm 4 GUID olarak geçer:

let u = Date.now().toString(16) + Math.random().toString(16) + '0'.repeat(16);
let guid = [u.substr(0,8), u.substr(8,4), '4000-8' + u.substr(13,3), u.substr(16,12)].join('-');
let u = Date.now().toString(16)+Math.random().toString(16)+'0'.repeat(16);
let guid = [u.substr(0,8), u.substr(8,4), '4000-8' + u.substr(13,3), u.substr(16,12)].join('-');
document.getElementById("unique").innerHTML = guid;
<div id="unique">
</div>

Düzenleme: Yukarıdaki kod niyetini takip eder, ancak RFC'nin harfini değil. Diğer tutarsızlıklar arasında kısa birkaç rasgele rakam var. (İhtiyacınız olursa daha fazla rasgele rakam ekleyin) Baş, bunun% 100 uyumlu kodla karşılaştırıldığında gerçekten hızlı olması. Burada GUID öğesinin geçerliliğini test edebilirsiniz

119
Simon Rigét

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX biçimindeki en hızlı GUID dizge üretme yöntemi gibi. Bu standart uyumlu bir GUID oluşturmaz.

Bu uygulamanın 10 milyon çalıştırması sadece bir tarayıcıda gördüğüm en hızlı olan 32.5 saniye sürüyor (döngüler/yinelemeler olmadan tek çözüm).

İşlev şu kadar basittir:

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

Performansı test etmek için bu kodu çalıştırabilirsiniz:

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

Eminim çoğunuz orada ne yaptığımı anlayacaksınızdır, ama belki bir açıklama yapması gereken en az bir kişi vardır:

Algoritma:

  • Math.random() işlevi, ondalık kesir noktasından sonra 16 basamaklı 0 ile 1 arasında bir ondalık sayı döndürür (for Example 0.4363923368509859).
  • Daha sonra bu sayıyı alıp dönüşürit, tabanı 16 olan bir dizgeye dönüştürürüz (yukarıdaki örnekten alacağız 0.6fb7687f).
    Math.random().toString(16).
  • Sonra 0. önekini kesiyoruz (0.6fb7687f => 6fb7687f) ve sekiz onaltılık Karakter uzunluğunda bir dize elde ediyoruz.
    (Math.random().toString(16).substr(2,8).
  • Bazen Math.random() işlevi, sonunda sıfırlardan dolayı (. Yukarıdaki örnekten, aslında sayı 0.4363'dır), Daha kısa bir sayı (örneğin 0.4363000000000000) döndürür. Bu yüzden bu dizeye "000000000" (dokuz tane sıfır olan bir dize) ekliyorum ve sonra onu dokuz karakter yapmak için substr() işleviyle kesiyorum (tam olarak sıfırları dolduruyorum).
  • Tam olarak dokuz sıfır eklemenin nedeni, Math.random() işlevinin tam olarak 0 veya 1 (her biri için 1/10 ^ 16 olasılığı) döndüreceği en kötü durum senaryosudur. Bu yüzden ona dokuz tane sıfır eklememiz gerekiyordu ("0"+"000000000" veya "1"+"000000000") ve sonra sekiz karakter uzunluğuyla ikinci dizinden (3. karakter) kesiyoruz. Vakaların geri kalanı için, sıfırların eklenmesi, sonuçta zarar vermeyecektir çünkü onu zaten kesmektedir.
    Math.random().toString(16)+"000000000").substr(2,8).

Meclis:

  • GUID şu biçimde XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX biçimindedir.
  • GUID 'ı 4 parçaya ayırdım, her parça 2 tipe (ya da formata) ayrıldı: XXXXXXXX ve -XXXX-XXXX.
  • Şimdi GUID ile bu iki tip kullanılarak GUID 'ı 4 parça çağrısı ile birleştirerek yapıyorum: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • Bu iki tip arasında farklılık göstermek için, bir çift yaratıcısı işlevine _p8(s) bir flag parametresi ekledim, s parametresi işleve çizgi ekleyip eklememeyi bildirir.
  • Sonunda GUID dizini şu zincirleme ile oluşturduk: _p8() + _p8(true) + _p8(true) + _p8() ve onu geri döndürün.

Blogumda bu yayına bağlantı

Keyfini çıkarın! :-)

82
Slavik Meltser

Burada en çok oylanan yanıtın , Chrome'un çarpışmalarını :

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

jsbin'de eğer test etmek istiyorsan.

60
ripper234

İşte 9 Ekim 2011 tarihli, kullanıcının bir yorumundan jed https://Gist.github.com/98288 :

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

Bu, mevcut en yüksek puanlı cevap ile aynı hedefi gerçekleştirir, ancak zorlama, özyineleme ve üstel gösterimden yararlanarak 50+ daha az baytta. Nasıl çalıştığını merak edenler için, işte fonksiyonun eski bir versiyonunun açıklamalı formu:

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

İşte ASCII güvenli bir GUID benzeri benzersiz tanımlayıcı oluşturmak için tamamen uyumlu olmayan ama çok performanslı bir uygulama.

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

26 [a-z0-9] karakter oluşturur, RFC uyumlu GUID'lerden hem daha kısa hem de daha benzersiz olan bir UID verir. İnsan okunabilirliği önemliyse kısa çizgiler önemsiz şekilde eklenebilir.

İşte bu fonksiyon için kullanım örnekleri ve zamanlamaları ve bu sorunun birkaç cevabı. Zamanlama, her biri 10 milyon yineleme olan Chrome m25 altında gerçekleştirildi.

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

İşte zamanlama kodu.

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

Node-uuid kullanabilirsiniz ( https://github.com/kelektiv/node-uuid )

Basit, hızlı nesil RFC4122 UUIDS.

Özellikler:

  • RFC4122 sürüm 1 veya sürüm 4 UUID'leri oluşturun
  • Node.js ve tarayıcılarda çalışır.
  • Destek platformlarında kriptografik olarak güçlü rastgele # nesil.
  • Az yer kaplama (Daha küçük bir şey ister misiniz? Şunu kontrol et! )

NPM Kullanarak Kur:

npm install uuid

Veya uuid'i tarayıcı aracılığıyla kullanma:

Raw Dosyasını İndir (uuid v1): https://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.js Raw Dosyasını İndir (uuid v4): https: // raw.githubusercontent.com/kelektiv/node-uuid/master/v4.js


Daha küçük ister misin? Şunlara göz atın: https://Gist.github.com/jed/982883


Kullanım:

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

Den sagi shkedy'nin teknik blogu :

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

Bir ActiveX denetimi kullanmayı gerektiren, ancak bunlardan uzak durmanın başka yöntemleri de var!

Edit: Hiçbir GUID jeneratörünün benzersiz anahtarlar garanti edemeyeceğine işaret etmeye değeceğini düşündüm ( wikipedia makalesini ) kontrol edin. Her zaman bir çarpışma şansı vardır. Bir GUID, çarpışma değişimini neredeyse sıfır seviyesine indirgeyecek kadar geniş bir anahtar evreni sunar.

31
Prestaul

Bir web servisi faydalı olacaktır. 

Hızlı Google bulundu: http://www.hoskinson.net/GuidGenerator/

Bu uygulama için kefil olamaz, ancak SOMEONE bir bonafide GUID jeneratörünü yayınlamalı.

Böyle bir web servisiyle, REST web servisini tüketen bir GUID web arayüzü geliştirebilir ve bir tarayıcıda javascript için AJAX üzerinden servis yapabilirsiniz.

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

DÜZENLE:

Bu işlevi kullanan projemi tekrar ziyaret ettim ve ayrıntılarını beğenmedim. - Fakat uygun rastlantısallık gerekiyordu.

Briguy37'nin cevabına ve bazı bit operatörlerine dayanarak, tampon büyüklüğünde pencereleri çıkarmak için bir sürüm.

Java'nın UUID'siyle uyumlu olmayan uuid'leri en son ayrıştırma Problemlerim olduğu için RFC Tip 4 (rastgele) şemaya uymalı.

29
sleeplessnerd

Bu konudaki en iyi cevapların bir kombinasyonu olarak basit JavaScript modülü.

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

Kullanımı: 

Guid.newGuid ()

"C6c2d12f-d76b-5739-e551-07e6de5b0807"

Guid.empty

"00000000-0000-0000-0000-000000000000"

28
kayz1

İyi ol 'wikipedia ' dan UUID in javascript uygulamasına bir bağlantı var.

Oldukça şık görünüyor ve müşterinin IP adresinin bir hash ile tuzlanmasıyla belki de geliştirilebilir. Bu karma, istemci tarafı javascript tarafından kullanılmak üzere html belgesi sunucu tarafına yerleştirilebilir.

GÜNCELLEME: Orijinal site bir karışıklık yaşadı, işte güncellenmiş versiyon

23
Dan

Bunun zaten bir sürü cevabı var ama maalesef grupta rastgele bir "doğru" yok. Aşağıdaki sürüm broofa'nın cevabının bir uyarlamasıdır, ancak mevcut olduğunda kripto kütüphanelerini kullanan "gerçek" rastgele bir işlevi ve geri dönüş olarak Alea () işlevini içerecek şekilde güncellenmiştir.

  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

GitHub'da JavaScript projesi - https://github.com/LiosK/UUID.js

UUID.js JavaScript için RFC uyumlu UUID üreteci.

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

Özellikler RFC 4122 uyumlu UUID'ler üretir.

Sürüm 4 UUID'ler (rastgele sayılardan UUID'ler) ve sürüm 1 UUID'ler (zamana dayalı UUID'ler) mevcuttur.

UUID nesnesi, U .__ için erişim dahil, UUID erişimine izin verir. UUID alanları.

JavaScript'in düşük zaman damgası çözünürlüğü rasgele .__ ile telafi edilir. sayılar.

21

Bu, sürüm 4 UUID (sözde rasgele sayılardan oluşturulan) oluşturma oluşturun:

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

İşte üretilen UUID'lerin bir örneği:

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

Kendi UUID/GUID jeneratörümü, bazı ekstralar burada ile ayarladı.

Aşağıdaki Kybos random sayı üretecini biraz daha şifreli bir ses için kullanıyorum.

Aşağıda benim baagoe.com gelen Mash ve Kybos yöntemleri ile benim senaryo hariç.

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

Daha iyi yol:

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
 }

Minimize edilmiş:

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

Broofa'nın cevabını anlamak istedim, bu yüzden genişletip yorum ekledim:

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 örneği

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

Bu sadece basit bir AJAX araması ...

Hala ilgilenen varsa, işte benim çözümüm.

Sunucu tarafında:

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

Müşteri tarafında:

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

Hızı dikkate alan rfc4122 sürüm 4 uyumlu bir çözüm isteyenler için (çok az Math.random () çağrısı)

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

Yukarıdaki fonksiyon, hız ve rastgelelik arasında iyi bir dengeye sahip olmalıdır.

11
John Fowler

Guid’in güzelce kullandığı bir jQuery eklentisi var @ http://plugins.jquery.com/project/GUID_Helper

jQuery.Guid.Value()

Dahili Kılavuzun değerini döndürür. Kılavuz belirtilmemişse, yeni bir tane döndürür (değer daha sonra dahili olarak depolanır).


jQuery.Guid.New()

Yeni bir Kılavuz döndürür ve değerini dahili olarak ayarlar.


jQuery.Guid.Empty()

Boş bir Kılavuz döndürür 00000000-0000-0000-0000-000000000000.


jQuery.Guid.IsEmpty()

Boole döndürür. Boş/tanımsız/boş/boş ise geçerlidir.


jQuery.Guid.IsValid()

Boole döndürür. Gerçek geçerli kılavuz, değilse yanlış.


jQuery.Guid.Set()

Guid'i tekrar getirir. Guid'i kullanıcı tarafından belirlenen Guid'e ayarlar, geçersizse boş bir guid döndürür.

10
Levitikon

Biliyorum, bu eski bir soru. Sadece bütünlük için ortamınız SharePoint ise, yeni bir kılavuz oluşturan SP.Guid.newGuid ( msdn link ) adında bir yardımcı program işlevi vardır. Bu işlev sp.init.js dosyasının içindedir. Bu işlevi yeniden yazarsanız (diğer bazı bağımlılıkları diğer özel işlevlerden kaldırmak için), şuna benzer:

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

Bu tarih esasına dayanır ve "benzersiz" olmasını sağlamak için rastgele bir sonek ekler . Css tanımlayıcıları için iyi çalışır .

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

Desteklenen tarayıcılarda crypto.getRandomValues(a) kullanan basit kod (IE11 +, iOS7 +, FF21 +, Chrome, Android Chrome). Math.random() işlevini kullanmaktan kaçınır, çünkü bu çarpışmalara neden olabilir (örneğin, gerçek bir durumda Muxa ile 4000 üretilen uuids için 20 çarpışma).

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

Notlar:

  • Kod okunabilirliği için optimize edilmiş hız değil, bu yüzden saniyede birkaç yüz uuid demek için uygun. Performansı ölçmek için http://jsbin.com/fuwigo/1 kullanarak dizüstü bilgisayarımda Chromium'da saniyede yaklaşık 10000 uuid () oluşturuyor.
  • Yalnızca "y" için 8 kullanır, çünkü kod okunabilirliğini basitleştirir (y, 8, 9, A veya B olabilir).
6
robocat

Belirli bir biçimde rastgele bir 128 bit dizgiye ihtiyacınız varsa, kullanabilirsiniz:

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

Hangi 2350143528-4164020887-938913176-2513998651 gibi bir şey döndürür.

6
Jonathan Potter

Bunun için kendi malzemelerinizi çırpmak yerine 1'den fazla katılımcının sağladığı iyi test edilmiş kodun kullanılması önemlidir. Bu, muhtemelen X tarayıcısında çalışan ancak Y'yi özdeşleştiren şeyleri hesaba katmayan, zira yalnızca rastgele tezahür etmekten ziyade, hataların araştırılması çok zor olan akıllı sürümden ziyade en kararlı kodu tercih etmek istediğiniz yerlerden biridir bazı kullanıcılar için. Şahsen https://github.com/aurigadl/uuid-js adresinde uuid-js kullanıyorum, böylece bower etkin oldu, böylece kolayca güncellemeleri alabilirim.

5
Shital Shah

Sadece iki mutasyon ile bir başka okunabilir değişken.

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

Bu işlevi aşağıdaki kullanıyorum, yararlı olabilir umarım.

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

Bir kılavuz üreteci ve onaylayıcı olan npm paketini guid kullanabilirsiniz.

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

Örnek:

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

UPDATE: Bu paket kullanımdan kaldırıldı. Bunun yerine uuid kullanın. 

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

Örnek: 

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

Google'a bırakan herkesin küçük bir yardımcı program kütüphanesi arayışında olması durumunda, ShortId ( https://www.npmjs.com/package/shortid ) bu sorunun tüm gereksinimlerini karşılamaktadır. İzin verilen karakterlerin ve uzunlukların belirlenmesine izin verir ve sıralı olmayan, tekrarlanmayan dizeleri garanti eder.

Bunu daha gerçek bir cevap haline getirmek için, kütüphanenin özü kısa kimliklerini üretmek için aşağıdaki mantığı kullanır:

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

Bunu, bu yaklaşımın en temel bölümlerini sadece yansıtacak şekilde düzenlemedim, bu yüzden yukarıdaki kod kütüphaneden ek bir mantık içeriyor. Yaptığı her şeyi merak ediyorsanız, kaynağa bir göz atın: https://github.com/dylang/shortid/tree/master/lib

3
MaxPRafferty

Bu komut dosyasını JavaScript'te GUID oluşturmak için yararlı buldum

https://github.com/addui/GUIDJS

var myGuid = GUID();
3
Dustin Poissant

Windows'ta Javascript kullananlar için (örneğin, WScript/CScript/MSHTA). Biri ActiveX kullanabilir. Özellikle, Scriptlet.Typelib nesnesi:

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

Bu cevabın sadece listelediğim teknolojiler üzerinde çalıştığını, Microsoft Edge'in bile hiçbir tarayıcıda çalışmadığını unutmayın! Öyleyse, kilometreniz bu cevaba göre değişecektir.

2
Stephen Quan

Kullanım davam için, global olarak benzersiz olacağı garantilenmiş bir kimlik oluşturmaya ihtiyacım vardı; istisnasız. Bir süre sorunla mücadele ettim ve tuid (Truly Unique ID) adlı bir çözüm buldum. İlk 32 karakterin sistem tarafından oluşturulmuş bir kimliği ve Epoch'tan beri milisaniyeyi temsil eden kalan rakamları oluşturur. Müşteri tarafında javascript kimliği oluşturmam gereken durumlarda, iyi çalışıyor. Bir göz atın:

https://github.com/mongoh/tuid

2
Rishi

Merhaba burada çalışan bir örnek 32 basamaklı Benzersiz UUID oluşturur. 

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

Tek bir 16-oktet TypedArray ve DataView kullanan bir cevap bulamadım, bu yüzden RFC başına 4 UUID sürümü oluşturmak için aşağıdaki çözümün burada duracağını düşünüyorum:

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
}

Bunu tercih ediyorum çünkü sadece standart ECMAScript platformunda mevcut olan fonksiyonlara dayanıyor.

1
amn

broofa'nın çalışmalarına dayanarak math.random () öğesine zaman damgası ekleyerek daha fazla rasgelik ekledim. 

Umarım yardımcı olabilir

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

Burada uuids üreten çok küçük bir fonksiyon bulabilirsiniz https://Gist.github.com/jed/982883

Son versiyonlardan biri:

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

Benzersiz bir tanımlama oluşturmak için basit bir çözüm, zaman belirteci kullanmak ve ona rasgele sayı eklemek. "Uuid-" ile önek yapmayı tercih ederim.

Aşağıdaki fonksiyon rastgele bir tür dizge üretecektir: uuid-14d93eb1b9b4533e6 . Bir 32 karakter rastgele dize oluşturmak gerekmez. 16 karakter rasgele dize, javascript'te benzersiz UUID'leri sağlamak için bu durumda yeterlidir.

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

Tamam, uuid paketini kullanarak sürüm 1, 3, 4 ve 5 UUID işlevini destekliyor

yarn add uuid

ve sonra:

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

Tam olarak belirtilen seçeneklerle de yapabilirsiniz:

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'

Daha fazla bilgi için, npm sayfasını ziyaret edin burada

0
Alireza

Sadece aynı şeyi yapmanın başka bir yolunu göndereceğimi düşündüm.

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

Bu biri için yararlı olabilir ...

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

Buna benzer bir çıktı elde etmek için replace ve crypto.getRandomValues ​​işlevlerini kullanabiliriz:

xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx

 enter image description here 

Bir opti çözümü arıyorsanız, crypto.getRandomValues(new Uint8Array(1))[0] işlevini bir dizi (32) ile değiştirmeliyiz.

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

Bu kodu almak için:

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

Çarpışma:

Google analytics'i beğenebilir ve :uuidv4() + "." + (+new Date()) ile bir zaman damgası ekleyebiliriz.

0
A-312

Bilim için. Bunu henüz kimsenin yapmadığını görmedim ... v4 uyumlu değil, ama kolayca değiştirilebildi. Bu, Uint8Array type öğesini genişletmeye ve uuid bayt değerlerini oluşturmak için crypto.getRandomValues ​​() kullanarak bir örnektir.

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