Создать GUID / UUID в JavaScript? - PullRequest
       581

Создать GUID / UUID в JavaScript?

3682 голосов
/ 20 сентября 2008

Я пытаюсь создать глобально уникальные идентификаторы в JavaScript. Я не уверен, какие подпрограммы доступны во всех браузерах, насколько «случайным» и затравленным является встроенный генератор случайных чисел и т. Д.

Значение GUID / UUID должно быть не менее 32 символов и должно оставаться в диапазоне ASCII, чтобы избежать проблем при их передаче.

Ответы [ 53 ]

7 голосов
/ 03 июня 2015

Простой код, который использует crypto.getRandomValues(a) в поддерживаемых браузерах (IE11 +, iOS7 +, FF21 +, Chrome, Android Chrome). Избегать использования Math.random(), потому что это может вызвать столкновения (например, 20 столкновений для 4000 сгенерированных uuids в реальной ситуации Muxa ).

function uuid() {
    function randomDigit() {
        if (crypto && crypto.getRandomValues) {
            var rands = new Uint8Array(1);
            crypto.getRandomValues(rands);
            return (rands[0] % 16).toString(16);
        } else {
            return ((Math.random() * 16) | 0).toString(16);
        }
    }
    var crypto = window.crypto || window.msCrypto;
    return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit);
}

Примечания:

  • Оптимизировано для удобочитаемости кода, а не скорости, поэтому подходит, например, для нескольких сотен единиц в секунду. Генерирует около 10000 uuid () в секунду в Chromium на моем ноутбуке, используя http://jsbin.com/fuwigo/1 для измерения производительности.
  • Используется только 8 для «y», потому что это упрощает читабельность кода (y может быть 8, 9, A или B).
6 голосов
/ 24 ноября 2017

Просто еще один более читаемый вариант с двумя мутациями.

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 голосов
/ 02 декабря 2013

Важно использовать хорошо протестированный код, который поддерживается более чем 1 участником, вместо того, чтобы создавать для этого свои собственные вещи. Это одно из тех мест, где вы, вероятно, хотите отдать предпочтение наиболее стабильному коду, а не самой короткой из возможных умных версий, которые работают в браузере X, но не учитывают особенности Y, которые часто приводят к очень трудным исследованиям ошибок, а не случайным образом. для некоторых пользователей. Лично я использую uuid-js на https://github.com/aurigadl/uuid-js, который включен, поэтому я могу легко получать обновления.

3 голосов
/ 22 марта 2016

Привет, вот рабочий пример, он генерирует 32-значный уникальный UUID.

function generateUUID() {
      var d = new Date();
      var k = d.getTime();
     var str = k.toString(16).slice(1)
    var UUID= 'xxxx-xxxx-4xxx-yxxx-xzx'.replace(/[xy]/g, function (c)
      {
        var r = Math.random() * 16 | 0;
        v = c == 'x' ? r : (r & 3 | 8);
        return v.toString(16);
      });
      var newString = UUID.replace(/[z]/, str)
      return newString;
    }
    var x = generateUUID()
    console.log(x,x.length)
3 голосов
/ 27 октября 2015

Вы можете использовать пакет npm guid , генератор guid и валидатор.

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

Пример:

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

ОБНОВЛЕНИЕ: Этот пакет устарел. Вместо этого используйте uuid .

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

Пример:

const uuidv4 = require('uuid/v4');
uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'
3 голосов
/ 01 февраля 2016

На всякий случай, если кто-то, заскочивший через Google, ищет небольшую служебную библиотеку, ShortId (https://www.npmjs.com/package/shortid) отвечает всем требованиям этого вопроса. Он позволяет указывать разрешенные символы и длину и гарантирует непоследовательные, неповторяющиеся строки.

Чтобы сделать это более реальным ответом, ядро ​​этой библиотеки использует следующую логику для создания своих коротких идентификаторов:

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

Я не редактировал это, чтобы отразить только самые основные части этого подхода, поэтому приведенный выше код включает некоторую дополнительную логику из библиотеки. Если вам интересно все, что он делает, посмотрите на источник: https://github.com/dylang/shortid/tree/master/lib

3 голосов
/ 11 августа 2016

Я нашел этот скрипт полезным для создания GUID в JavaScript

https://github.com/addui/GUIDJS

var myGuid = GUID();
3 голосов
/ 04 апреля 2014

Я использую эту функцию ниже, надеюсь, она может быть полезной.

    function NewGuid()
         {
           var sGuid="";
           for (var i=0; i<32; i++)
            {
              sGuid+=Math.floor(Math.random()*0xF).toString(0xF);
            }
           return sGuid;
         }
2 голосов
/ 08 июня 2014

Для моего варианта использования мне потребовалось генерирование идентификатора, который гарантированно был уникальным во всем мире; без исключений. Некоторое время я боролся с этой проблемой и придумал решение под названием tuid (действительно уникальный идентификатор). Он генерирует идентификатор, причем первые 32 символа генерируются системой, а оставшиеся цифры представляют миллисекунды с начала эпохи. В ситуациях, когда мне нужно генерировать идентификаторы на клиентском JavaScript, это работает хорошо. Посмотрите:

https://github.com/mongoh/tuid

2 голосов
/ 07 ноября 2018

основываясь на работе broofa, я добавил еще немного случайности, добавив метку времени в math.random ()

Надеюсь, это поможет

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