javascript - simple - web browser uuid




JavaScript로 GUID/UUID를 만드시겠습니까? (20)

JavaScript에서 전역 적으로 고유 한 식별자를 만들려고합니다. 모든 브라우저에서 어떤 루틴을 사용할 수 있는지 확실하지 않습니다. 어떻게 "임의로"및 내장 된 난수 생성기를 시드했는지 등등.

GUID / UUID는 32 자 이상이어야하며 주위를 지나칠 때 문제가 발생하지 않도록 ASCII 범위를 유지해야합니다.


broofa의 대답은 꽤 매끄 럽습니다. 실제로 인상적인 영리한 ... 정말로 ... rfc4122 호환, 다소 읽기 쉽고 컴팩트합니다. 굉장해!

그러나 당신이 그 정규식을보고 있다면, 많은 replace() 콜백, toString()Math.random() 함수 호출 (여기서 4 비트의 결과 만 사용하고 나머지는 낭비)을 보면, 성능에 대해 궁금해하기. 사실, joelpt는 generateQuickGUID 사용 generateQuickGUID 일반 GUID 속도에 대한 RFC를 버리기로 결정했습니다.

그러나 속도 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.

따라서 여섯 번째 반복 최적화를 통해 가장 인기있는 답변을 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);
});

따라서 임의의 16 진수를 임의의 16 진수로 대체하고 임의의 데이터로 y 를 대체합니다 (RFC 사양에 따라 상위 2 비트를 10 제외하고). 정규 표현식은 - 또는 4 문자와 일치하지 않으므로 거래하지 않아도됩니다. 그들과 함께. 매우 매끄러운.

가장 먼저 알아야 할 것은 함수 호출은 값 비싸며 정규 표현식과 같습니다 (단 1 개만 사용하고 32 개의 콜백, 매치마다 하나씩, Math.random () 및 v.를 호출하는 32 개의 콜백 각각에 있음). 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 확인하거나 replace() 콜백 대신) while 루프를 사용하면 거의 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 함수 호출을 모두 최적화 클래식 (look-up table)으로 제거합니다. 간단한 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 준수 비트 위치를 처리해야하기 때문에 까다 롭지 만 너무 어렵지 않습니다. 그런 다음 0x00 - 0xff를 저장하기 위해 더 큰 조회 테이블 (16x16 또는 256)을 만들어야하고 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을 사용하여이 작업을 재 시도하고 성능을 유지했습니다. 그러나 무작위 데이터를 4 개의 변수에 할당하고 룩업 테이블을 사용하고 적절한 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];
}

수정 됨 : http://jcward.com/UUID.js - UUID.generate()

재미있는 점은 16 바이트 무작위 데이터를 생성하는 것이 쉬운 부분이라는 것입니다. 전체 트릭은 RFC 준수를 사용하여 문자열 형식으로 표현하며 16 바이트의 무작위 데이터, 풀어지지 않은 루프 및 찾아보기 테이블로 가장 잘 수행됩니다.

내 논리가 정확하기를 바랍니다. 이런 지루한 비트 작업에서 실수를하는 것은 매우 쉽습니다. 그러나 출력은 나에게 좋게 보인다. 코드 최적화를 통해이 미친듯한 즐거움을 만끽하시기 바랍니다!

권장 사항 : 나의 주요 목표는 잠재적 인 최적화 전략을 보여주고 가르치는 것이 었습니다. 다른 답변은 좋은 UUID를 생성하는 데 중요한 충돌 및 진정한 난수와 같은 중요한 주제를 다룹니다.


나는 Broofa의 청결 함이 얼마나 깨끗한 지 정말 좋아하지만, Math.random 빈약 한 구현이 충돌의 기회를 놓치게되는 것은 불행한 일입니다.

다음은 타임 스탬프의 16 진수 부분으로 처음 13 진수를 오프셋 ietf.org/rfc/rfc4122.txt 문제를 해결하는 비슷한 ietf.org/rfc/rfc4122.txt 버전 4 호환 솔루션입니다. 그렇게하면 Math.random 이 동일한 시드에 있다고하더라도 두 클라이언트가 동일한 UUID를 얻으려면 정확히 동일한 밀리 초 (또는 10,000+ 년 후)에 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);
    });
}


테스트 할 바이올린이 있습니다.


다음은 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 에서 테스트하고 싶다면.


다음은 ietf.org/rfc/rfc4122.txt , 4.4 절 (진정으로 무작위 또는 의사 난수에서 UUID를 생성하기위한 알고리즘)에 기반한 코드입니다.

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

문자열 생성기 메서드와 같은 가장 빠른 GUID는 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 입니다. 표준 호환 GUID를 생성하지 않습니다.

이 구현의 1 천만 건의 실행은 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() 함수는 소수점 이하 16 자리의 0에서 1 사이의 십진수를 반환합니다 (예 : 0.4363923368509859 ).
  • 그런 다음이 숫자를 가져 와서 밑이 16 인 문자열로 변환합니다 (위의 예제에서 우리는 0.6fb7687f0.6fb7687f ).
    Math.random().toString(16) .
  • 그런 다음 0. 접두어 ( 0.6fb7687f => 6fb7687f )를 6fb7687f 8 개의 16 진수로 된 문자열을 가져옵니다.
    (Math.random().toString(16).substr(2,8) .
  • 때로는 Math.random() 함수는 끝에있는 0으로 인해 더 짧은 숫자 (예 : 0.4363 )를 반환합니다 (위의 예에서 실제로 숫자는 0.4363000000000000 ). 그래서이 문자열에 "000000000" (9 개의 0이있는 문자열)을 추가 한 다음 substr() 함수로 잘라내어 9 개의 문자를 정확하게 채 웁니다 (오른쪽에 0을 채움).
  • 정확히 9 개의 0을 추가하는 이유는 Math.random() 함수가 정확하게 0 또는 1 (각각에 대해 1 / 10 ^ 16의 확률 Math.random() 을 반환 할 때인 최악의 시나리오 때문입니다. 그래서 우리는 9 개의 0을 ( "0"+"000000000" 또는 "1"+"000000000" ) 추가 한 다음 두 번째 인덱스 (세 번째 문자)에서 8 자 길이로 잘라야했습니다. 나머지 경우에는 0을 추가해도 어쨌든 결과가 잘리지 않으므로 결과에 아무런 영향을 미치지 않습니다.
    Math.random().toString(16)+"000000000").substr(2,8) .

어셈블리 :

  • GUID 형식은 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 입니다.
  • 나는 GUID를 4 조각으로 나누었고 각 조각은 XXXXXXXX-XXXX-XXXX 두 가지 유형 (또는 형식)으로 나뉘었다.
  • 이제 다음 두 가지 유형을 사용하여 GUID를 작성하여 다음과 같이 4 개로 호출하여 GUID를 어셈블합니다. XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX .
  • 이 두 유형을 구분하기 위해 플래그 생성자 함수 _p8(s) 플래그 매개 변수를 추가했습니다. s 매개 변수는 대시를 추가할지 여부를 함수에 알려줍니다.
  • 결국 우리는 _p8() + _p8(true) + _p8(true) + _p8() 체인을 사용하여 GUID를 생성하고이를 반환합니다.

내 블로그에이 게시물에 대한 링크

즐겨! :-)


웹 서비스가 유용 할 것입니다.

빠른 Google 발견 : http://www.hoskinson.net/GuidGenerator/

이 구현을 보증 할 수 없지만, 누군가가 bonafide GUID 생성기를 게시해야합니다.

이러한 웹 서비스를 사용하면 GUID 웹 서비스를 사용하는 REST 웹 인터페이스를 개발할 수 있으며 AJAX를 통해 브라우저에서 javascript로 서비스 할 수 있습니다.


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

ActiveX 컨트롤을 사용하는 다른 방법이 있지만 멀리 떨어져있어!

편집 : 아무 GUID 생성기 고유 키를 보장 할 수 지적 가치가 줄 알았는데 ( 위키디아 문서 확인). 항상 충돌의 기회가 있습니다. GUID는 단순히 충돌의 변화를 거의 없애기 위해 충분히 큰 키 우주를 제공합니다.


RFC4122 버전 4 호환 솔루션의 경우,이 한 줄짜리 (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 모듈 [Disclaimer : I 'm author]을 고려해보십시오.이 모듈 은 가능한 경우 고품질 RNG API를 사용합니다.

Update, 2015-08-26 : 사이드 노트에서이 gist 는 특정 충돌 확률에 도달하기 전에 얼마나 많은 ID를 생성 할 수 있는지 결정하는 방법을 설명합니다. 예를 들어, 3.26x10 15 버전 4 RFC4122 UUID를 사용하면 충돌 가능성이 100 만 개입니다.

업데이트, 2017-06-28 : Chrome 개발자 는 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());


그냥 간단한 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.");
    }
);

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

속도 고려 사항이있는 rfc4122 버전 4 규격 솔루션을 원한다면 (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("");
}

위 함수는 속도와 무작위성 사이에서 적절한 균형을 유지해야합니다.


이 스레드에서 가장 좋은 답변의 조합으로 간단한 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"


GitHub의 자바 스크립트 프로젝트 - 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에 대한 다양한 액세스를 허용합니다.

자바 스크립트의 낮은 타임 스탬프 해상도는 난수로 보상됩니다.


Guid의 멋지게 처리하는 jQuery 플러그인은 http://plugins.jquery.com/project/GUID_Helper

jQuery.Guid.Value()

내부 Guid의 값을 반환합니다. guid가 지정되어 있지 않은 경우, 새로운 GUID를 돌려줍니다 (값은 내부적으로 저장됩니다).

jQuery.Guid.New()

새 Guid를 반환하고 내부적으로 값을 설정합니다.

jQuery.Guid.Empty()

빈 Guid 00000000-0000-0000-0000-000000000000을 반환합니다.

jQuery.Guid.IsEmpty()

부울을 반환합니다. empty / undefined / blank / null 인 경우는 true

jQuery.Guid.IsValid()

부울을 반환합니다. 진정한 유효한 guid, 그렇지 않은 경우 false.

jQuery.Guid.Set()

Retid Guid. Guid를 사용자가 지정한 Guid로 설정합니다 (잘못된 경우). 빈 GUID를 반환합니다.


글쎄, 이미 많은 답변이 있지만, 불행히도 무리에 "진정한"무작위가 없습니다. 아래 버전은 broofa의 답변이지만, 사용 가능한 경우 암호화 라이브러리를 사용하는 "진정한"임의 함수와 Alea () 함수를 대체하도록 업데이트되었습니다.

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

나는 그것이 오래된 질문이라는 것을 알고있다. 완전성을 위해 귀하의 환경이 SharePoint 일 경우 새로운 guid를 만드는 유틸리티 함수 SP.Guid.newGuid( msdn link )가 있습니다. 이 함수는 sp.init.js 파일 안에 있습니다. 이 함수를 다른 개인 함수에서 다른 종속성을 제거하기 위해 다시 작성하면 다음과 같이 보입니다.

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

에서 좋은 똑똑한 '위키 피 디아 UUID의 자바 스크립트 구현에 대한 링크가 있습니다.

상당히 우아 해 보입니다. 클라이언트의 IP 주소 해시로 소금을 쳐서 향상시킬 수 있습니다. 이 해시는 클라이언트 측 자바 스크립트에서 사용할 수 있도록 html 문서 서버 측에 삽입 될 수 있습니다.

업데이트 : 원래 사이트에 셔플이 있었는데 여기에 업데이트 된 버전이 있습니다.


이것은 날짜를 기반으로하며 고유성을 "보장"하기 위해 임의의 접미사를 추가합니다. css 식별자로 잘 작동합니다. 항상 같은 것을 반환하고 해킹하기 쉽습니다.

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

  // 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 밀리 초 이상 떨어져 생성 된 경우 ID는 100 % 고유합니다.

더 짧은 간격으로 2 개의 ID가 생성되고 무작위 방법이 실제로 무작위라고 가정하면 99.99999999999999 %의 ID가 생성되어 전역 적으로 고유하게 나타날 수 있습니다 (1에서 10의 ^ 15 충돌)

더 많은 자릿수를 추가하여이 수를 늘릴 수 있지만 100 % 고유 ID를 생성하려면 글로벌 카운터를 사용해야합니다.

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





uuid