javascript - uuid用途 - uuid重複




在JavaScript中創建GUID/UUID? (20)

我正在嘗試在JavaScript中創建全局唯一標識符。 我不確定所有瀏覽器上可用的例程,“隨機”和內置隨機數生成器的種子等等。

GUID / UUID應至少為32個字符,並應保持在ASCII範圍內,以避免傳遞它們時出現問題。



broofa的答案非常光滑,確實 - 令人印象深刻的聰明,真的... rfc4122兼容,有點可讀,緊湊。 真棒!

但是如果你正在查看那個正則表達式,那些很多replace()回調, toString()Math.random()函數調用(他只使用4位結果並浪費其餘部分),你可以開始想知道表現。 實際上,joelpt甚至決定使用generateQuickGUID將RFC轉換為通用GUID速度。

但是,我們能否獲得速度 RFC合規性? 我說是! 我們能保持可讀性嗎? 嗯...不是真的,但是如果你跟著它就很容易。

但首先,我的結果,與broofa, guid (接受的答案)和非rfc兼容的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.

因此,通過我的第6次優化迭代,我擊敗了最受歡迎的答案超過12 ,接受的答案超過9 ,而快速不符合要求的答案為2-3 。 我仍然符合rfc4122標準。

對如何感興趣? 我已將完整的資源放在http://jsfiddle.net/jcward/7hyaC/3/http://jsperf.com/uuid-generator-opt/4

要解釋一下,讓我們從broofa的代碼開始:

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

所以它用任意隨機十六進制數字替換xy用隨機數據替換(除了根據RFC規範強制前2位到10 ),並且正則表達式與-4字符不匹配,因此他不必處理跟他們。 非常非常光滑。

首先要知道的是函數調用是很昂貴的,正則表達式也是如此(儘管他只使用1,它有32個回調,每個匹配一個,並且在32個回調中的每個回調中都調用Math.random()和v。的toString(16))。

性能的第一步是消除RegEx及其回調函數,而是使用簡單的循環。 這意味著我們必須處理-4字符,而broofa沒有。 另外,請注意我們可以使用String Array索引來保持其光滑的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;
}

基本上,相同的內部邏輯,除了我們檢查-4 ,並使用while循環(而不是replace()回調)使我們幾乎提高了3倍!

下一步是桌面上的一個小步驟,但在移動設備上有一個不錯的區別。 讓我們減少Math.random()調用並利用所有這些隨機位,而不是使用隨機緩衝區拋出87%的隨機緩衝區,每次迭代都會移出它們。 讓我們也將該模板定義移出循環,以防它有所幫助:

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
}

這節省了10-30%,具體取決於平台。 不錯。 但是下一個重要的步驟完全消除了toString函數調用與優化經典 - 查找表。 一個簡單的16元素查找表將在更短的時間內執行toString(16)的工作:

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
}

下一個優化是另一個經典。 由於我們在每次循環迭代中只處理4位輸出,所以讓我們將循環次數減半,每次迭代處理8位。 這很棘手,因為我們仍然需要處理符合RFC的位位置,但這並不難。 然後我們必須創建一個更大的查找表(16x16或256)來存儲0x00 - 0xff,我們只在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
}

我嘗試了一次處理16位的e6(),仍然使用256個元素的LUT,它顯示了優化的收益遞減。 儘管迭代次數較少,但內部邏輯由於處理增加而變得複雜,並且在桌面上執行相同,並且在移動設備上只有約10%的速度。

要應用的最終優化技術 - 展開循環。 由於我們循環固定次數,因此我們可以在技術上手動完成這一切。 我用一個隨機變量r嘗試了一次,我不斷重新分配,並且性能下降了。 但是有四個變量預先分配隨機數據,然後使用查找表,並應用適當的RFC位,這個版本將它們全部抽取:

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

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

有趣的是,生成16字節的隨機數據很容易。 整個技巧是以符合RFC的字符串格式表達它,並且用16字節的隨機數據,一個展開的循環和查找表來完成它。

我希望我的邏輯是正確的 - 在這種繁瑣的工作中犯錯誤很容易。 但輸出對我來說很好。 我希望你通過代碼優化享受這種瘋狂的旅程!

建議:我的主要目標是展示和教授潛在的優化策略。 其他答案涵蓋了重要的主題,如衝突和真正的隨機數,這對於生成良好的UUID非常重要。


以下是2011年10月9日用戶jedhttps://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)}

這實現了與當前評分最高的答案相同的目標,但是通過利用強制,遞歸和指數表示法,可以減少50多個字節。 對於那些好奇的工作方式,這裡是舊版本函數的註釋形式:

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

以下是最高投票答案的組合,以及針對Chrome碰撞的解決方法:

generateGUID = (typeof(window.crypto) != 'undefined' && 
                typeof(window.crypto.getRandomValues) != 'undefined') ?
    function() {
        // If we have a cryptographically secure PRNG, use that
        // https://.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://.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上,如果你想測試它。


在這方面有幾次嘗試。 問題是:您想要實際的GUID,還是只想看起來像GUID的隨機數? 生成隨機數很容易。

function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

但請注意,此類值不是正版GUID

注意 :提供的代碼段不遵循RFC4122,後者要求必須將版本( 4 )集成到生成的輸出字符串中。 如果您需要兼容的GUID,請不要使用此答案

使用:

var uuid = guid();

演示:

function guid() {
  return "ss-s-s-s-sss".replace(/s/g, s4);
}

function s4() {
  return Math.floor((1 + Math.random()) * 0x10000)
    .toString(16)
    .substring(1);
}

document.getElementById('jsGenId').addEventListener('click', function() {
  document.getElementById('jsIdResult').value = guid();
})
input { font-family: monospace; }
<button id="jsGenId" type="button">Generate GUID</button>
<br>
<input id="jsIdResult" type="text" placeholder="Results will be placed here..." readonly size="40"/>


對於符合RFC4122版本4的解決方案,這種RFC4122 (ish)解決方案是我能想到的最緊湊的解決方案:

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

更新,2015-06-02 :請注意,UUID唯一性在很大程度上依賴於底層隨機數生成器(RNG)。 上面的解決方案使用Math.random()來簡潔,但Math.random() 不能保證是高質量的RNG。 有關詳細信息,請參閱Adam Hyland 關於Math.random()優秀文章 。 對於更強大的解決方案,請考慮類似uuid模塊 [免責聲明:我是作者],它使用更高質量的RNG API。

更新,2015-08-26 :作為附註,這個gist描述瞭如何確定在達到一定的碰撞概率之前可以生成多少個ID。 例如,對於3.26x10 15版本4 RFC4122 UUID,您有一個百萬分之一的碰撞機會。

更新,2017-06-28Chrome開發人員在Chrome,Firefox和Safari中討論Math.random PRNG質量狀態的好文章 。 tl; dr - 截至2015年底,它“非常好”,但不是加密質量。 為了解決這個問題,這裡是上述解決方案的更新版本,該解決方案使用ES6, crypto API和一些JS嚮導,我不能相信

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


我想了解broofa的答案,所以我擴展了它並添加了評論:

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

我真的很喜歡Broofa的答案是多麼乾淨,但不幸的是, Math.random糟糕實現留下了碰撞的機會。

這是一個類似的ietf.org/rfc/rfc4122.txt版本4兼容解決方案,通過將前13個十六進制數字偏移時間戳的十六進制部分來解決該問題。 這樣,即使Math.random在同一個種子上,兩個客戶端都必須在完全相同的毫秒(或10,000多年後)生成UUID才能獲得相同的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);
    });
}


這是一個小小的測試。


最快的GUID,如字符串生成器方法,格式為XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 。 這不會生成符合標準的GUID。

這個實現的一千萬次執行只需要32.5秒,這是我在瀏覽器中見過的最快的(沒有循環/迭代的唯一解決方案)。

功能如下:

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

要測試性能,可以運行以下代碼:

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

我相信你們中的大多數人都會明白我在那裡做了什麼,但也許至少有一個人需要解釋:

算法:

  • Math.random()函數返回0到1之間的十進制數,小數點後的位數為16位(例如0.4363923368509859 )。
  • 然後我們取這個數字並將其轉換為帶有16的字符串(從上面的例子中我們得到0.6fb7687f )。
    Math.random().toString(16)
  • 然後我們切斷0.前綴( 0.6fb7687f => 6fb7687f )並得到一個長度為八個十六進製字符的字符串。
    (Math.random().toString(16).substr(2,8)
  • 有時, Math.random()函數將返回較短的數字(例如0.4363 ),因為最後的零(從上面的示例,實際上數字是0.4363000000000000 )。 這就是為什麼我要附加到這個字符串"000000000" (一個包含九個零的字符串),然後用substr()函數將其substr() ,使其準確地為九個字符(向右填充零)。
  • 準確添加九個零的原因是由於更糟糕的情況,即Math.random()函數將準確地返回0或1(每個的概率為1/10 ^ 16)。 這就是為什麼我們需要向它添加九個零( "0"+"000000000""1"+"000000000" ),然後從長度為8個字符的第二個索引(第3個字符)中刪除它。 對於其他情況,添加零不會損害結果,因為它無論如何都會切斷它。
    Math.random().toString(16)+"000000000").substr(2,8)

大會:

  • GUID的格式如下XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  • 我將GUID分為4個部分,每個部分分為2種類型(或格式): XXXXXXXX-XXXX-XXXX
  • 現在我正在構建使用這兩種類型的GUID來組裝帶有4個調用的GUID,如下所示: XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX
  • 為了_p8(s)這兩種類型,我在一對創建者函數_p8(s)添加了一個flag參數, s參數告訴函數是否添加破折號。
  • 最後我們使用以下鏈接構建GUID: _p8() + _p8(true) + _p8(true) + _p8() ,並返回它。

在我的博客上鍊接到這篇文章

請享用! :-)


簡單的JavaScript模塊作為此線程中最佳答案的組合。

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

用法:

Guid.newGuid()

“c6c2d12f-d76b-5739-e551-07e6de5b0807”

Guid.empty

“00000000-0000-0000-0000-000000000000”


這只是一個簡單的AJAX調用......

如果有人仍然感興趣,這是我的解決方案。

在服務器端:

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

在客戶端:

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

這是一個完全不兼容但非常高性能的實現,用於生成類似於ASCII的GUID類唯一標識符。

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

生成26個[a-z0-9]字符,產生的UID比RFC兼容的GUID更短且更獨特。 如果人類可讀性很重要,可以簡單地添加虛線。

以下是此功能的使用示例和時間以及此問題的其他幾個答案。 計時在Chrome m25下進行,每次迭代1000萬次。

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

這是時間碼。

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

GitHub上的JavaScript項目 - https://github.com/LiosK/UUID.js

UUID.js適用於JavaScript的符合RFC的UUID生成器。

請參閱RFC 4122 ietf.org/rfc/rfc4122.txt

功能生成符合RFC 4122的UUID。

版本4 UUID(來自隨機數的UUID)和版本1 UUID(基於時間的UUID)可用。

UUID對象允許對UUID的各種訪問,包括對UUID字段的訪問。

JavaScript的低時間戳分辨率由隨機數補償。


你可以使用node-uuid(https://github.com/kelektiv/node-uuid

簡單,快速生成ietf.org/rfc/rfc4122.txt UUIDS。

特徵:

  • 生成RFC4122版本1或版本4 UUID
  • 在node.js和瀏覽器中運行。
  • 密碼學上強大的隨機#生成在支持平台上。
  • 佔地面積小(想要更小的東西嗎?https://gist.github.com/982883

使用NPM安裝:

npm install uuid

或者通過瀏覽器使用uuid:

下載原始文件(uuid v1):https://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.jshttps://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.js下載原始文件(uuid v4):https://raw.githubusercontent.com/kelektiv/node-uuid/master/v4.jshttps://raw.githubusercontent.com/kelektiv/node-uuid/master/v4.js

想要更小?看看這個:https//gist.github.com/jed/982883

用法:

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

奇怪的是,沒有人提到過這個但是為了完整性,npm上有大量的guid生成器我願意打賭他們中的大多數也在瀏覽器中工作。


好的維基百科,有一個鏈接到UUID的javascript實現。

它看起來相當優雅,也許可以通過使用客戶端IP地址的哈希來改進。可以將此哈希插入到html文檔服務器端以供客戶端javascript使用。

更新:原始網站有一個shuffle,這是更新版本


有一個jQuery插件可以很好地處理Guid的http://plugins.jquery.com/project/GUID_Helper

jQuery.Guid.Value()

返回內部Guid的值。如果未指定guid,則返回一個新值(然後在內部存儲值)。

jQuery.Guid.New()

返回一個新的Guid並在內部設置它的值。

jQuery.Guid.Empty()

返回空Guid 00000000-0000-0000-0000-000000000000。

jQuery.Guid.IsEmpty()

返回布爾值。如果為空/未定義/空/空,則為真。

jQuery.Guid.IsValid()

返回布爾值。真正有效的guid,如果沒有,則為false。

jQuery.Guid.Set()

Retrns Guid。將Guid設置為用戶指定的Guid,如果無效,則返回空guid。


調整與一些額外的我自己的UUID / GUID發電機here

我正在使用以下Kybos隨機數生成器來加密聲音。

下面是我的腳本,其中包含來自baagoe.com的Mash和Kybos方法。

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

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

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

如果ID的生成間隔超過1毫秒,則它們是100%唯一的。

如果以較短的間隔生成兩個ID,並且假設隨機方法是真正隨機的,那麼這將產生99.99999999999999%可能是全局唯一的ID(在10 ^ 15中的1中發生衝突)

您可以通過添加更多數字來增加此數字,但要生成100%唯一ID,您需要使用全局計數器。

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





uuid