javascript - generate - uuid react js




Crear GUID/UUID en JavaScript? (20)

Aquí hay un código basado en ietf.org/rfc/rfc4122.txt , sección 4.4 (Algoritmos para crear un UUID a partir de un número verdaderamente aleatorio o pseudoaleatorio).

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

Estoy tratando de crear identificadores únicos a nivel mundial en JavaScript. No estoy seguro de qué rutinas están disponibles en todos los navegadores, cómo es "aleatorio" y siembra el generador de números aleatorios incorporado, etc.

El GUID / UUID debe tener al menos 32 caracteres y debe permanecer en el rango ASCII para evitar problemas al pasarlos.


Aquí hay una combinación de la respuesta más votada , con una solución para las colisiones de 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);
        });
    };

En jsbin si quieres probarlo.


Aquí hay una solución con fecha del 9 de octubre de 2011 de un comentario del usuario jed en https://gist.github.com/982883 :

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

Esto logra el mismo objetivo que la respuesta actual con la calificación más alta , pero en más de 50 bytes menos al explotar la coacción, la recursión y la notación exponencial. Para aquellos que saben cómo funciona, aquí está la forma comentada de una versión anterior de la función:

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

Del blog técnico de 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;
}

Hay otros métodos que involucran el uso de un control ActiveX, ¡pero manténgase alejado de estos!

EDITAR: pensé que valía la pena señalar que ningún generador GUID puede garantizar claves únicas (consulte el artículo de wikipedia ). Siempre hay una posibilidad de colisiones. Un GUID simplemente ofrece un universo suficientemente grande de claves para reducir el cambio de colisiones a casi nula.


Ha habido un par de intentos en esto. La pregunta es: ¿desea GUID reales o solo números aleatorios que parezcan GUID? Es bastante fácil generar números al azar.

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

Sin embargo, tenga en cuenta que dichos valores no son GUID genuinos .

Nota : el fragmento de código proporcionado no sigue a RFC4122, que requiere que la versión ( 4 ) tenga que estar integrada en la cadena de salida generada. No use esta respuesta si necesita GUID compatibles.

Utilizar:

var uuid = guid();

Manifestación:

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


La respuesta de Broofa es bastante hábil, de hecho, impresionantemente inteligente, realmente ... compatible con rfc4122, algo legible y compacta. ¡Increíble!

Pero si estás viendo esa expresión regular, muchas de las funciones de callbacks replace() , toString() y Math.random() (donde solo usa 4 bits del resultado y desperdician el resto), puedes comenzar preguntarse sobre el rendimiento. De hecho, joelpt incluso decidió deshacerse de RFC para la velocidad GUID genérica con generaQuickGUID.

Pero, ¿podemos obtener velocidad y cumplimiento RFC? ¡Yo digo si! ¿Podemos mantener la legibilidad? Bueno ... no realmente, pero es fácil si sigues adelante.

Pero primero, mis resultados, en comparación con broofa, guid (la respuesta aceptada), y el generateQuickGuid activación rápida no compatible con rfc:

                  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.

Entonces, en mi sexta iteración de optimizaciones, superé la respuesta más popular en más de 12X , la respuesta aceptada en más de 9X , y la respuesta rápida que no cumplía con 2-3X . Y sigo siendo compatible con rfc4122.

¿Interesado en cómo? He puesto la fuente completa en http://jsfiddle.net/jcward/7hyaC/3/ y en http://jsperf.com/uuid-generator-opt/4

Para una explicación, comencemos con el código de 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);
});

Así que reemplaza x con cualquier dígito hexadecimal aleatorio, y con datos aleatorios (excepto el forzar los 2 bits superiores a 10 según la especificación RFC), y la expresión regular no coincide con los 4 caracteres, por lo que no tiene que repartir con ellos. Muy, muy resbaladizo.

Lo primero que se debe saber es que las llamadas a funciones son caras, como lo son las expresiones regulares (aunque solo usa 1, tiene 32 devoluciones de llamada, una para cada coincidencia, y en cada una de las 32 devoluciones de llamada llama Math.random () y v. aString (16)).

El primer paso hacia el rendimiento es eliminar el RegEx y sus funciones de devolución de llamada y, en su lugar, utilizar un bucle simple. Esto significa que tenemos que lidiar con los - y 4 caracteres, mientras que broofa no lo hizo. Además, tenga en cuenta que podemos usar la indexación de String Array para mantener su arquitectura de plantilla de 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;
}

Básicamente, la misma lógica interna, excepto que verificamos para - o 4 , y usar un bucle while (en lugar de callbacks de replace() ) nos permite una mejora de casi 3X.

El siguiente paso es uno pequeño en el escritorio, pero hace una diferencia decente en el móvil. Hagamos menos llamadas Math.random () y utilicemos todos esos bits aleatorios en lugar de tirar el 87% de ellos con un búfer aleatorio que se desplaza fuera de cada iteración. También movamos esa definición de plantilla fuera del bucle, en caso de que ayude:

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
}

Esto nos ahorra 10-30% dependiendo de la plataforma. No está mal. Pero el siguiente gran paso es deshacerse de las llamadas a la función toString con un clásico de optimización: la tabla de consulta. Una simple tabla de búsqueda de 16 elementos realizará el trabajo de toString (16) en mucho menos tiempo:

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
}

La próxima optimización es otro clásico. Como solo manejamos 4 bits de salida en cada iteración de bucle, recortemos el número de bucles a la mitad y procesemos 8 bits en cada iteración. Esto es complicado ya que todavía tenemos que manejar las posiciones de bit compatibles con RFC, pero no es demasiado difícil. Luego tenemos que hacer una tabla de búsqueda más grande (16x16 o 256) para almacenar 0x00 - 0xff, y la construimos solo una vez, fuera de la función 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
}

Probé un e6 () que procesa 16 bits a la vez, aún utilizando la LUT de 256 elementos, y mostró los rendimientos decrecientes de la optimización. A pesar de que tenía menos iteraciones, la lógica interna se complicó por el aumento del procesamiento, y funcionó igual en el escritorio, y solo un 10% más rápido en el móvil.

La técnica de optimización final para aplicar - desenrolla el bucle. Ya que estamos repitiendo un número fijo de veces, técnicamente podemos escribir todo esto a mano. Intenté esto una vez con una única variable aleatoria r que seguí reasignando, y el rendimiento disminuyó. Pero con cuatro variables asignadas datos aleatorios por adelantado, luego utilizando la tabla de búsqueda y aplicando los bits RFC adecuados, esta versión los fuma a todos:

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

Modualizado: http://jcward.com/UUID.js - UUID.generate()

Lo curioso es que generar 16 bytes de datos aleatorios es la parte fácil. Todo el truco es expresarlo en formato String con conformidad RFC, y se logra de manera más estricta con 16 bytes de datos aleatorios, un bucle desenrollado y una tabla de búsqueda.

Espero que mi lógica sea correcta: es muy fácil cometer un error en este tedioso trabajo de bits. Pero las salidas me quedan bien. Espero que hayas disfrutado este viaje loco a través de la optimización de código!

Tenga en cuenta: mi objetivo principal era mostrar y enseñar posibles estrategias de optimización. Otras respuestas cubren temas importantes como colisiones y números verdaderamente aleatorios, que son importantes para generar buenos UUID.


Realmente me gusta lo limpia que es la respuesta de Broofa , pero es desafortunado que las malas implementaciones de Math.random dejen la posibilidad de colisión.

Aquí hay una solución compatible con la versión 4 de ietf.org/rfc/rfc4122.txt que resuelve ese problema al compensar los primeros 13 números hexadecimales con una parte hexadecimal de la marca de tiempo. De esa manera, incluso si Math.random está en la misma semilla, ambos clientes tendrían que generar el UUID en el mismo milisegundo (o 10,000 años más tarde) para obtener el mismo 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);
    });
}


Aquí hay un violín para probar.


Un servicio web sería útil.

Búsqueda rápida de Google: http://www.hoskinson.net/GuidGenerator/

No puedo responder por esta implementación, pero ALGUIEN debe publicar un generador GUID de buena fe.

Con un servicio web de este tipo, podría desarrollar una interfaz web REST que consuma el servicio web GUID y lo sirva a través de AJAX para javascript en un navegador.


Esto crea UUID de la versión 4 (creado a partir de números pseudoaleatorios):

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

Aquí hay una muestra de los UUID generados:

682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136

La mejor manera:

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
 }

Minimizado:

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}

Muestra ES6

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

Para aquellos que desean una solución compatible con rfc4122 versión 4 con consideraciones de velocidad (pocas llamadas a 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("");
}

La función anterior debe tener un balance decente entre velocidad y aleatoriedad.


Ajusté mi propio generador UUID / GUID con algunos extras here .

Estoy usando el siguiente generador de números aleatorios de Kybos para ser un poco más criptográficamente sólido.

A continuación se incluye mi script con los métodos Mash y Kybos de baagoe.com excluidos.

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

Bueno, esto ya tiene muchas respuestas, pero desafortunadamente no hay un "verdadero" azar en el grupo. La versión a continuación es una adaptación de la respuesta de Broofa, pero actualizada para incluir una función aleatoria "verdadera" que utiliza bibliotecas criptográficas cuando están disponibles, y la función Alea () como alternativa.

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

Es extraño que nadie haya mencionado esto todavía, pero para completar, hay una gran cantidad de generadores guid en npm . Estoy dispuesto a apostar que la mayoría de ellos también funcionan en el navegador.


Este se basa en la fecha y agrega un sufijo aleatorio para "asegurar" la singularidad. Funciona bien para los identificadores css. Siempre devuelve algo así y es fácil de hackear:

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

Lo sé, es una vieja pregunta. Solo para estar completo, si su entorno es SharePoint, hay una función de utilidad llamada SP.Guid.newGuid( msdn link ) que crea una nueva guía. Esta función está dentro del archivo sp.init.js. Si reescribe esta función (para eliminar algunas otras dependencias de otras funciones privadas), se ve así:

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

Proyecto de JavaScript en GitHub - https://github.com/LiosK/UUID.js

UUID.js El generador de UUID compatible con RFC para JavaScript.

Consulte RFC 4122 ietf.org/rfc/rfc4122.txt .

Características Genera UUIDs compatibles con RFC 4122.

Los UUID de la versión 4 (UUID de números aleatorios) y los UUID de la versión 1 (UUID basados ​​en el tiempo) están disponibles.

El objeto UUID permite una variedad de acceso al UUID, incluido el acceso a los campos UUID.

La baja resolución de la marca de tiempo de JavaScript se compensa con números aleatorios.


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

Si los ID se generan con más de 1 milisegundo de diferencia, son 100% únicos.

Si se generan dos ID a intervalos más cortos, y suponiendo que el método aleatorio es realmente aleatorio, esto generaría ID que tienen una probabilidad del 99.99999999999999% de ser único a nivel mundial (colisión en 1 de 10 ^ 15)

Puede aumentar este número agregando más dígitos, pero para generar un 100% de ID únicas deberá usar un contador global.

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





uuid