52 Pregunta: Crear GUID / UUID en JavaScript?

pregunta creada en Fri, Dec 26, 2014 12:00 AM

Estoy intentando crear identificadores únicos globales en JavaScript. No estoy seguro de qué rutinas están disponibles en todos los navegadores, qué tan "aleatorio" es 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.

    
3706
  1. Los GUID cuando están representados, ya que las cadenas tienen al menos 36 y no más de 38 caracteres de longitud y coinciden con el patrón ^ \{? [a-zA-Z0-9] {36}? \} $Y, por lo tanto, siempre son ascii.
    2008-09-19 20: 35: 06Z
  2. David Bau proporciona un generador de números aleatorios mucho mejor y fácil de sembrar en davidbau.com/archives/2010/01/30/… Escribí un enfoque ligeramente diferente para generar UUID en blogs.cozi.com/tech/2010/04/generating-uuids-in-javascript.html
    2010-05-04 23: 09: 46Z
  3. jsben.ch/#/Lbxoe - Aquí un punto de referencia con las diferentes funciones de abajo
    2016-10-24 17: 59: 14Z
  4. uuid-random usa bien PRNG y es muy rápido.
    2016-10-29 16: 37: 56Z
  5. Llega tarde (¡muy tarde!) a la fiesta aquí, pero @AnthonyWJones no debería leer tu expresión regular: ^ \{? [a-fA-F0-9] {36 }? \} $
    2017-02-13 11: 40: 45Z
30 Respuestas                              30                         

UUIDs (Universent Unique IDentifier), también conocidos como GUIDs (Globally Unique IDentifier), según RFC 4122 , son identificadores con una cierta garantía de exclusividad.

La mejor manera de generarlos es seguir las instrucciones de implementación en dicho RFC, usar una de las muchas implementaciones de código abierto de la comunidad.

Una popular herramienta de código abierto para trabajar con UUID en JavaScript es node-uuid

Tenga en cuenta que solo generar aleatoriamente los identificadores byte por byte, o carácter por carácter, no le dará las mismas garantías que una implementación conforme. Además, es muy importante que los sistemas que trabajan con UUID compatibles puedan elegir no aceptar los generados aleatoriamente, y muchos validadores de código abierto en realidad comprobarán una estructura válida.

Un UUID debe tener este formato:

 
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Donde las posiciones M y N solo pueden tener ciertos valores. En este momento, los únicos valores válidos para M son 1, 2, 3, 4 y 5, por lo que la generación aleatoria de esa posición haría que la mayoría de los resultados sean inaceptables.

    
2159
2019-05-22 14: 01: 40Z
  1. En realidad, el RFC permite UUID que se crean a partir de números aleatorios. Solo tienes que girar un par de bits para identificarlo como tal. Ver apartado 4.4. Algoritmos para crear un UUID a partir de números verdaderamente aleatorios o pseudoaleatorios: rfc-archive. org /getrfc.php? rfc = 4122
    2008-09-19 20: 28: 33Z
  2. ¿Podría alguien explicarme este código? Parece que la función S4 intenta obtener unnúmero hexadecimal aleatorio entre 0x10000 y 0x20000, luego genera los últimos 4 dígitos. Pero ¿por qué en el bit o con 0? ¿No debería ser un noop? Además, ¿es el 0x10000 a 0x20000 solo un truco para evitar tener que lidiar con los 0's principales?
    2010-10-26 22: 56: 39Z
  3. En Chrome, este código no siempre genera un GUID de tamaño correcto. La longitud varía entre 35 y 36
    2012-09-13 21: 38: 16Z
  4. ¿Cómo puede una respuesta tan obviamente errónea obtener tantos votos? Incluso el código es incorrecto, ya que no hay un 4 en la posición correcta. en.wikipedia.org/wiki/Globally_unique_identifier
    2013-01-21 09: 28: 56Z
  5. Esta respuesta se rompió en la revisión 5 cuando se eliminaron "1 + ..." y "subcadena (1)". Esos bits garantizaron la longitud consistente.
    2013-02-07 19: 12: 32Z

Para una RFC4122 solución compatible con la versión 4, esta solución de una sola línea (ish) es el más compacto que pude encontrar:

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

Actualización, 2015-06-02 : tenga en cuenta que la singularidad de UUID se basa en gran medida en el generador de números aleatorios (RNG) subyacente. La solución anterior utiliza Math.random() por brevedad, sin embargo, Math.random() no es no garantizado como un RNG de alta calidad. Consulte excelente redacción en Math.random () de Adam Hyland para obtener más información. Para una solución más robusta, considere algo como el módulo uuid [Descargo de responsabilidad: soy el autor] , que utiliza API RNG de mayor calidad cuando están disponibles.

Actualización, 2015-08-26 : Como nota al margen, esta gist describe cómo determinar cuántas ID se pueden generar antes de alcanzar una cierta probabilidad de colisión. Por ejemplo, con los UUID 3.26x10 15 versión 4 RFC4122, tiene una probabilidad de colisión de 1 en un millón.

Actualización, 2017-06-28 : A buen artículo de los desarrolladores de Chrome sobre el estado de la calidad PRNG de Math.random en Chrome, Firefox y Safari. tl; dr - A finales de 2015 es "bastante bueno", pero no de calidad criptográfica. Para solucionar este problema, aquí hay una versión actualizada de la solución anterior que utiliza ES6, crypto API y un poco de JS wizardy No puedo tomar crédito por :

 
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());
    
3563
2019-05-25 12: 50: 39Z
  1. ¿Es seguro usar este código para generar identificadores únicos en el cliente y luego usar esos identificadores como claves principales para guardar objetos en el servidor?
    2011-04-21 07: 04: 14Z
  2. ... (cont.) Las probabilidades de dos ID generadas por esta función que colisionan son, literalmente, astronómicamente pequeñas. Todos menos 6 de los 128 bits de la ID se generan de forma aleatoria, lo que significa que para cualquiera de las dos ID, existe una posibilidad de 1 en 2 ^^ 122 (o 5.3x10 ^^ 36) de que colisionen.
    2011-04-28 22: 37: 39Z
  3. Publiqué una pregunta sobre colisiones stackoverflow.com/questions/6906916/…
    2011-08-02 03: 23: 28Z
  4. Seguramente la respuesta a la pregunta de @ Muxa es 'no'? Nunca es realmente seguro confiar en algo que viene del cliente. Supongo que depende de la probabilidad de que sus usuarios activen una consola de javascript y cambien manualmente la variable para que ellos deseen. O podrían simplemente PONER DE VUELTA la identificación que quieren. También dependería de si el usuario que selecciona su propia ID va a causar vulnerabilidades. De cualquier manera, si es un ID de número aleatorio que está ingresando en una tabla, probablemente lo esté generando del lado del servidor, de modo que sepa que tengo control sobre el proceso.
    2012-11-01 14: 34: 05Z
  5. @ DrewNoakes: los UUID no son solo una cadena de # de números completamente aleatorios. El "4" es la versión de uuid (4 = "aleatorio"). Las marcas "y" donde se debe incrustar la variante uuid (diseño del campo, básicamente). Consulte las secciones 4.1.1 y 4.1.3 de ietf.org/rfc/rfc4122.txt para más información.
    2012-11-27 22: 13: 12Z

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

Aquí hay una solución RFC4122 similar que resuelve ese problema al compensar la primera 13 números hexadecimales por una porción 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.

    
748
2018-04-02 18: 34: 30Z
  1. Tenga en cuenta que new Date().getTime() no se actualiza cada milisegundo. No estoy seguro de cómo afecta esto a la aleatoriedad esperada de su algoritmo.
    2012-03-18 17: 27: 22Z
  2. Creo que esta es la mejor respuesta simplemente porque usa la fecha en su generación. Sin embargo, si tiene una pila de navegadores moderna, recomiendo Date.now() a new Date().getTime()
    2013-06-28 19: 47: 42Z
  3. performance.now sería aun mejor. A diferencia de Date.now, las marcas de tiempo devueltas por performance.now() no están limitadas a una resolución de un milisegundo. En su lugar, representan tiempos como números de punto flotante con una precisión de microsegundos . Además, a diferencia de Date.now, los valores devueltos por performance.now () siempre aumentan a una tasa constante , independientemente del reloj del sistema, que puede ser ajustado manualmente o sesgado por un software como el Protocolo de tiempo de red.
    2014-03-13 04: 25: 07Z
  4. @ daniellmb Probablemente debería haber vinculado a MDN u otro para mostrar documentación real y no un polyfill;)
    2014-07-08 19: 38: 17Z
  5. FYI, según el pie de página del sitio, todas las contribuciones de los usuarios en el sitio están disponibles bajo la licencia cc by-sa 3.0.
    2015-02-04 01: 34: 59Z

la respuesta de Broofa es bastante hábil, de hecho, impresionantemente inteligente, realmente ... compatible con rfc4122, algo legible y compacta. Impresionante!

Pero si está viendo esa expresión regular, esas muchas llamadas de retorno de replace(), llamadas de función de toString() y Math.random() (donde solo usa 4 bits del resultado y desperdicia el resto), puede comenzar a preguntarse sobre el rendimiento. De hecho, Joelpt incluso decidió deshacerse de RFC para genéricosVelocidad GUID con generateQuickGUID.

Pero, ¿podemos obtener la velocidad de y el cumplimiento de RFC? Yo digo, ¡SÍ! ¿Podemos mantener la legibilidad? Bueno ... en realidad no, pero es fácil si sigues.

Pero primero, mis resultados, en comparación con broofa, guid (la respuesta aceptada), y el generateQuickGuid que no cumple 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 con más de 12X , la respuesta aceptada con más de 9X y la rápida respuesta que no cumple con las normas por 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);
});

Entonces, 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 caracteres - o 4, por lo que no Tengo que lidiar con ellos. Muy, muy hábil.

Lo primero que se debe saber es que las llamadas a funciones son caras, al igual que 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.toString (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 caracteres - y 4, mientras que broofa no lo hizo. Además, tenga en cuenta que podemos usar la indexación de matriz de cadenas para mantener su arquitectura de plantilla de cadena pulida:

 
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 - o 4, y usar un bucle while (en lugar de replace() devoluciones de llamada) nos da una mejora de casi 3X!

El siguiente paso es uno pequeño en el escritorio, pero marca una diferencia decente en dispositivos móviles. 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 siguiente 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ó debido al aumento en el procesamiento, y funcionó igual en el escritorio, y solo un 10% más rápido en dispositivos móviles.

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

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

Lo gracioso 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 tipo de trabajo tedioso. Pero las salidas me quedan bien. Espero que hayas disfrutado de 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.

    
371
2018-08-03 19: 45: 08Z
  1. jsperf.com le permitiría capturar los datos y ver los resultados en los navegadores y dispositivos.
    2014-02-24 15: 40: 04Z
  2. Hola @chad, buenas preguntas. k podría ser movido afuera, pero eso no mejoró el rendimiento arriba y hace que el alcance sea más complicado. Y construir una matriz y unirla al rendimiento mata de forma extraña el rendimiento. Pero una vez más, ¡siéntete libre de experimentar!
    2014-02-24 19: 23: 19Z
  3. Me gustaría saber cómo se compara node-uuid.js. En mi trabajo allí comencé con un enfoque más en el rendimiento, algunos de los cuales permanecen. Pero desde entonces me he apartado de eso, prefiriendo tener un código más legible /mantenible. La razón es que uuid perf simplemente no es un problema en el mundo real. Por lo general, los Uuids se crean junto con operaciones mucho más lentas (por ejemplo, realizar una solicitud de red, crear y persistir un objeto modelo), donde eliminar cosas de unos pocos microsegundos simplemente no importa.
    2015-06-02 15: 14: 59Z
  4. Este código aún contiene un par de errores: las Math.random()*0xFFFFFFFF líneas deben ser Math.random()*0x100000000 para una aleatoriedad total, y >>>0 se debe usar en lugar de |0 para mantener los valores sin firmar (aunque con el código actual creo que sale bien a pesar de que están firmados). Finalmente, sería una muy buena idea en estos días usar window.crypto.getRandomValues si está disponible, y recurrir a Math.random solo si es absolutamente necesario. Math.random puede tener menos de 128 bits de entropía, en cuyo caso esto sería más vulnerable a las colisiones de lo necesario.
    2015-07-18 17: 55: 51Z
  5. Haber aplicado todos los consejos de @Dave y publicado la fuente ES6 /Babel muy clara aquí: codepen.io/avesus/pen/wgQmaV?editors=0012
    2017-02-10 20: 51: 57Z

Aquí hay un código basado en RFC 4122 , sección 4.4 (Algoritmos para crear un UUID de Truly Random o Pseudo-Random Number).

 
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;
}
    
147
2011-10-25 22: 37: 37Z
  1. Esto no produce los guiones necesarios para que c # lo analice en un System.Guid. Se reproduce de esta manera: B42A153F1D9A4F92990392C11DD684D2, cuando se debe procesar como: B42A153F-1D9A-4F92-9903-92C11DD684D2
    2011-10-25 16: 24: 42Z
  2. El ABNF de la especificación incluye los caracteres "-", así que actualicé para ser compatible.
    2011-10-25 22: 40: 40Z
  3. Personalmente odio los guiones, pero son propios de cada uno. ¡Oye, por eso somos programadores!
    2012-01-23 16: 20: 23Z
  4. Debe declarar el tamaño del arreglo de antemano en lugar de dimensionarlo dinámicamente al crear el GUID. var s = new Array(36);
    2013-03-25 20: 03: 59Z
  5. @ 491010 de Levitikon .NET debería analizar Guid.Parse() en un Guid, simplemente bien. No necesita tener los guiones.
    2013-11-12 08: 08: 21Z
 B42A153F1D9A4F92990392C11DD684D2

 
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 cortosy, asumiendo que el método aleatorio es verdaderamente aleatorio, esto generaría ID que son 99.9999999999999999% probables de ser únicas 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.

Si realmente necesita el cumplimiento de RFC, este formato pasará como GUID de la versión 4 válida:

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

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

Editar: El código anterior sigue la intención, pero no la letra del RFC. Entre otras discrepancias hay unos pocos dígitos aleatorios cortos. (Agregue más dígitos aleatorios si lo necesita) La ventaja es que esto es realmente rápido, en comparación con el código que cumple con el 100%. Puede probar su GUID aquí

    
110
2019-06-13 09: 01: 11Z
  1. ¿Esto no es UUID?
    2017-12-26 23: 28: 06Z
  2. No. UUID /GUID es un número de 122 bits (+ seis bits reservados). Puede garantizar la singularidad a través de un servicio de contador global, pero a menudo se transmite a tiempo, la dirección MAC y la aleatoriedad. ¡Los UUID no son aleatorios! El UID que sugiero aquí no está completamente comprimido. Podría comprimirlo, a un entero de 122 bits, agregar los 6 bits predefinidos y los bits aleatorios adicionales (eliminar algunos bits del temporizador) y terminar con un UUID /GUID perfectamente formado, que luego tendría que convertir a hexadecimal. Para mí, eso realmente no agrega nada más que el cumplimiento a la longitud del ID.
    2018-02-18 00: 05: 21Z
  3. ¡La retransmisión en las direcciones MAC para la exclusividad en las máquinas virtuales es una mala idea!
    2018-02-18 00: 48: 45Z
  4. Hago algo como esto, pero con los caracteres iniciales y algunos guiones (por ejemplo,
    const uid = (new Date()).getTime().toString(16) + Math.random().toString(16).substring(2) + "0".repeat(16);
    const guid = uid.substr(0,8) + '-' + uid.substr(8,4) + '-4000-8' + uid.substr(12,3) + '-' + uid.substr(15,12);
    
    para crear
    var u = (new Date()).getTime().toString(16) + 
        Math.random().toString(16).substring(2) + "0".repeat(16);
    var guid = u.substr(0,8) + '-' + u.substr(8,4) + '-4000-8' + 
        u.substr(12,3) + '-' + u.substr(15,12);
    document.getElementById("unique").innerHTML = guid;
    <div id="unique">
    </div>
    . Esto hace que la ID también se duplique como un campo "creado en"
    2019-06-06 19: 23: 44Z

El GUID más rápido como método generador de cadenas en el formato

var u = (new Date()).getTime().toString(16) + 
    Math.random().toString(16).substring(2) + "0".repeat(16);
var guid = u.substr(0,8) + '-' + u.substr(8,4) + '-4000-8' + 
    u.substr(12,3) + '-' + u.substr(15,12);
document.getElementById("unique").innerHTML = guid;
. Esto no genera un GUID que cumpla con los estándares.

Diez millones de ejecuciones de esta implementación toman solo 32.5 segundos, que es el más rápido que he visto en un navegador (la única solución sin bucles /iteraciones).

La función es tan simple como:

 
<div id="unique">
</div>

Para probar el rendimiento, puede ejecutar este código:

 [slug, date, random].join("_")

Estoy seguro de que la mayoría de ustedes comprenderá lo que hice allí, pero tal vez haya al menos una persona que necesite una explicación:

El algoritmo:

  • La función usr_1dcn27itd_hj6onj6phr devuelve un número decimal entre 0 y 1 con 16 dígitos después del punto de fracción decimal (para ejemplo XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX).
  • Luego tomamos este número y lo convertimos a una cadena con base 16 (del ejemplo anterior obtendremos  
    /**
     * Generates a GUID string.
     * @returns {String} The generated GUID.
     * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
     * @author Slavik Meltser (slavik@meltser.info).
     * @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');
    
    .
  • Luego cortamos el prefijo Math.random() (0.4363923368509859 = >  0.6fb7687f) y obtener una cadena con ocho hexadecimales caracteres de longitud.
    Math.random().toString(16).
  • A veces la función 0. regresará número más corto (por ejemplo, 0.6fb7687f), debido a los ceros al final (del ejemplo anterior, en realidad el número es 6fb7687f). Es por eso que estoy agregando a esta cadena (Math.random().toString(16).substr(2,8) (una cadena con nueve ceros) y luego la corto con la función Math.random() para que tenga nueve caracteres exactamente (rellene los ceros a la derecha).
  • El motivo para agregar exactamente nueve ceros se debe al peor escenario, que es cuando la función 0.4363 devolverá exactamente 0 o 1 (probabilidad de 1/10 ^ 16 para cada uno de ellos). Es por eso que necesitamos agregar nueve ceros (0.4363000000000000 o "000000000"), y luego cortarlo del segundo índice (3er carácter) con una longitud de ocho caracteres. Para el resto de los casos, la adición de ceros no dañará el resultado porque de todos modos se está cortando.
    substr().

El conjunto:

  • El GUID está en el siguiente formato Math.random().
  • He dividido el GUID en 4 partes, cada pieza divided en 2 tipos (o formatos): "0"+"000000000" y "1"+"000000000".
  • Ahora estoy creando el GUID utilizando estos 2 tipos para ensamblar el GUID con la llamada de 4 piezas, de la siguiente manera: Math.random().toString(16)+"000000000").substr(2,8) XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX XXXXXXXX -XXXX-XXXX.
  • Para diferir entre estos dos tipos, agregué un parámetro de marca a la función XXXXXXXX del creador de pares, el parámetro -XXXX-XXXX le dice a la función si agregar o no guiones.
  • Finalmente, construimos el GUID con el siguiente encadenamiento: -XXXX-XXXX y lo devolvemos.

Enlace a esta publicación en mi blog

¡Disfruta! :-)

    
85
2018-07-15 19: 10: 23Z
  1. Esta implementación es incorrecta. Ciertos caracteres del GUID requieren un tratamiento especial (por ejemplo, el dígito 13 debe ser el número 4).
    2013-11-12 08: 12: 27Z
  2. @ JLRishe, tienes razón, no cumple con los estándares RFC4122. Pero sigue siendo una cadena aleatoria que se parece a GUID. Saludos :-)
    2013-11-24 22: 33: 09Z
  3. Buen trabajo, pero las técnicas de optimización clásicas lo hacen 6 veces más rápido (en mi navegador); consulte mi respuesta
    2014-02-25 19: 23: 51Z

Aquí hay una combinación de la respuesta más votada , con una solución para Colisiones de Chrome :

 XXXXXXXX

En jsbin si quieres probarlo.

    
62
2017-05-23 11: 47: 36Z
  1. Creo que en IE es en realidad window.msCrypto en lugar de window.crypto. Podría ser bueno revisar ambos. Consulte msdn.microsoft.com/en- us /library /ie /dn265046 (v = vs.85) .aspx
    2014-04-17 20: 44: 57Z
  2. tenga en cuenta que la primera versión, el `window.crypto.getRandomValues ​​_p8(s) xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`es el rendimiento s.
    2016-09-03 07: 58: 23Z

Aquí hay una implementación totalmente no compatible pero de gran rendimiento para generar un identificador único tipo GUID seguro para ASCII.

 _p8() + _p8(true) + _p8(true) + _p8()

Genera 26 caracteres [a-z0-9], lo que genera un UID que es más corto y más exclusivo que los GUID compatibles con RFC. Los guiones se pueden agregar de forma trivial si la legibilidad humana es importante.

Aquí hay ejemplos de uso y tiempos para esta función y varias de las respuestas de esta pregunta. El tiempo se realizó bajo Chrome m25, 10 millones de iteraciones cada uno.

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

Aquí está el código de tiempo.

 , does not keep the Version 4 UUIDs format defined by RFC 4122. That is instead of     
57
2013-01-21 21: 52: 57Z

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 :

 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Esto logra el mismo objetivo que actual más alto respuesta clasificada , pero en más de 50 bytes menos explotando la coerción, la recursión, unNotación exponencial nd. Para aquellos que saben cómo funciona, esta es la forma comentada de una versión anterior de la función:

 
function generateQuickGuid() {
    return Math.random().toString(36).substring(2, 15) +
        Math.random().toString(36).substring(2, 15);
}
    
56
2017-05-23 10: 31: 37Z
  1. En TypeScript use esto:
    >>> 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
    
    2018-08-07 22: 45: 54Z

De blog técnico de sagi shkedy :

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

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

Editar: pensé que valía la pena señalar que ningún generador GUID puede garantizar claves únicas (consulte 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 ninguna.

    
37
2018-11-26 06: 57: 40Z
  1. Tenga en cuenta que esto no es un GUID en el sentido técnico, porque no hace nada para garantizar la unicidad. Eso puede o no puede importar dependiendo de su aplicación.
    2008-09-19 20: 07: 33Z
  2. Lo mismo ocurre con la respuesta de Stephen. Si necesita singularidad, defínalo del lado del servidor, ¡con la esperanza de poder llegar a un algoritmo adecuado!
    2008-09-19 20: 08: 56Z
  3. No se garantiza que GUID sea único ... El universo de claves creadas es simplemente lo suficientemente grande como para hacer que las colisiones sean casi imposibles.
    2008-09-19 20: 13: 10Z
  4. Una nota rápida sobre el rendimiento. Esta solución crea un total de 36 cadenas para obtener un solo resultado. Si el rendimiento es crítico, considere crear una matriz y unirse según lo recomendado por: tinyurl.com/y37xtx Investigaciones adicionales lo indican puede que no importe, así que YMMV: tinyurl.com/3l7945
    2008-09-22 18: 14: 32Z
  5. Con respecto a la singularidad, vale la pena señalar que la versión 1,3 y los 5 UUID son deterministas en la forma en que la versión 4 no lo es. Si las entradas a estos generadores uuid (id de nodo en v1, espacio de nombres y nombre en v3 y v5) son únicas (como se supone que son), entonces los UUID resultantes serán únicos. En teoría, de todos modos.
    2017-06-29 13: 26: 41Z

Puede usar node-uuid ( https://github.com/kelektiv/node-uuid)

Generación simple y rápida de RFC4122 UUIDS.

Características:

  • Genere los UUID de la versión 1 o 4 de RFC4122
  • Se ejecuta en node.js y navegadores.
  • Criptográficamente fuerte # generación aleatoria en plataformas de soporte.
  • Huella pequeña (¿Quieres algo más pequeño? ¡Mira esto! )

Instalar usando NPM:

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

O usando uuid a través del navegador:

Descargue el archivo sin formato (uuid v1): https: //raw. githubusercontent.com/kelektiv/node-uuid/master/v1.js Descargue el archivo sin formato (uuid v4): https://raw.githubusercontent.com /kelektiv/node-uuid/master/v4.js


¿Quieres aún más pequeño? Mira esto: https://gist.github.com/jed/982883


Uso :

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

ES6:

 export const UUID = function b (a: number): string { return a ? (a^Math.random()*16>>a/4).toString(16) : (''+[1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, b) };     
34
2018-12-09 21: 17: 53Z
  1. El archivo sin formato está muerto.
    2017-04-13 03: 50: 33Z
  2. @ Edward Olamisan Nueva fuente actualizada para reemplazar la versión heredada.
    2017-04-14 21: 31: 05Z
  3. Esta es la respuesta correcta, tbh. Solo usa esta biblioteca.
    2017-05-20 05: 29: 49Z
  4. ES6 version:
    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;
    }
    
    2017-05-20 05: 30: 30Z
  5. @ justin.m.chase no debería ser const id = uuid
    2018-02-22 01: 07: 19Z

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 que lo sirva a través de AJAX para javascript en un navegador.

    
31
2008-09-19 20: 35: 27Z
  1. Hice, hospedé y usé este: timjeanes. es /guid . Utiliza .NET para generar un nuevo GUID y lo devuelve sin ningún problema adicional. También funcionará sobre JSONP.
    2010-06-02 20: 35: 53Z
  2. ¿Un servicio web para servir un GUID, en realidad? Eso es casi tan extraño como escribir un servicio web para servir números aleatorios, a menos que realmente necesite números aleatorios producidos por alguna fuente de ruido físico conectada a un servidor, es decir.
    2014-09-09 06: 21: 57Z
  3. El único problema con un servicio de red es que la red podría estar inactiva.
    2017-12-26 19: 09: 17Z
  4. El enlace no está actualizado, el servicio no funciona.
    2018-03-04 18: 16: 21Z
 
npm install uuid

EDITAR:

Revisé mi proyecto que estaba usando esta función y no me gustó la verbosidad. - Pero necesitaba la aleatoriedad adecuada.

Una versión basada en la respuesta de Briguy37 y algunos operadores bit a bit para extraer ventanas de tamaño nibble del búfer.

Debería cumplir con el esquema RFC Tipo 4 (aleatorio), ya que tuve problemas al analizar UUID no compatibles con el UUID de Java la última vez.

    
31
2015-09-11 22: 32: 03Z
  1. 2011-12-12 10: 04: 42Z
  2. Gracias por intentarlo. Lo preparé para una extensión de cromo. No verifiqué los hechos que leí en elternt (tm) sobre Firefox soportándolo. También vale la pena mencionar que no cumple con el RFC, el UUID aleatorio (Versión 4) debe tener dos lugares con valores fijos: en.wikipedia.org/wiki/…
    2011-12-12 17: 03: 30Z

Módulo de JavaScript simple como una combinación de las mejores respuestas en este hilo.

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

Uso:

  
    

Guid.newGuid()

         

"c6c2d12f-d76b-5739-e551-07e6de5b0807"

         

Guid.empty

         

"00000000-0000-0000-0000-000000000000"

  
    
29
2017-06-29 13: 29: 06Z
  1. Lo que preocupa a todas respuestas es que parece ok que JavaScript almacene el
    import uuid from 'uuid/v4';
    const id = uuid();
    
    como un import uuid from 'uuid/v4'; let id = uuid();. Su respuesta, al menos, aborda el mucho almacenamiento más eficiente con un
    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);
        });
    };
    
    . La función
    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());
    debe utilizar la representación binaria en un JavaScript GUID
    2014-05-04 11: 03: 59Z
  2. ¿No debería string incluir un '4' al comienzo de la tercera sección, como lo hace Uint16Array?
    2015-02-01 21: 05: 21Z
  3. ¡Buena respuesta! Convertí el código en un fragmento y solucioné el problema de compatibilidad con IE11, de acuerdo con esta pregunta.
    2017-05-18 11: 56: 11Z
  4. Estos UUID producidos por este código son débiles pero compatibles con RFC (_guid), o fuertes pero no compatibles con RFC (_cryptoGuid). El primero usa Math.random (), que ahora se sabe que es un RNG pobre. Este último no puede establecer los campos de versión y variante.
    2017-06-29 13: 37: 48Z
  5. @ broofa - ¿Qué sugeriría para que sea fuerte y compatible con RFC? ¿Y por qué _cryptoGuid no es compatible con RFC?
    2018-03-15 09: 57: 43Z

De good ol 'wikipedia hay un enlace a una implementación de javascript de UUID.

Se ve bastante elegante, y tal vez podría mejorarse compartiendo con un hash de la dirección IP del cliente. Tal vez este hash podría insertarse en el lado del servidor del documento html para que lo use el javascript del lado del cliente.

ACTUALIZACIÓN: El sitio original ha sido aleatorio, aquí está el versión actualizada

    
25
2011-02-16 19: 25: 35Z
  1. El enlace está muerto. ¿Puedes proporcionar una alternativa?
    2011-01-12 14: 04: 05Z
  2. Esta implementación es buena porque, a diferencia de las respuestas anteriores, también incluye la marca de tiempo que debería mejorar la singularidad de los navegadores con un generador de números aleatorios de mala calidad.
    2011-09-30 00: 17: 01Z

Bueno, esto ya tiene un montón de respuestas, pero desafortunadamenteno hay un "verdadero" al 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.

 toString     
24
2016-04-11 13: 51: 11Z
  1. Debe comentar la línea object ya que trunca el resultado a 32 bits. Las operaciones de bits son solo 32 bits en JS. Además, si lo aplica solo al final, los 3 bits bajos ya se han perdido al generar un valor de 53 bits, ya que el primer bucle crea un valor de 56 bits (255 * 2 ^ 48). En su lugar, necesita usar este código: `var byte = byteArray [i]; if (p + 8 > bits_needed) byte & = (255 > > p + 8 - bits_needed); rval + = byte * Math.pow (2, p); `Puede ver la prueba aquí: jsfiddle.net /xto6969y /1
    2015-05-02 08: 57: 20Z
  2. También puede considerar usar var crypto = window.crypto || window.msCrypto vea msdn.microsoft.com/library/dn265046(v = vs.85) .aspx
    2015-05-02 09: 00: 19Z
  3. Actualizado en ambos conteos.
    2015-06-02 14: 10: 14Z
  4. Usé su script y obtuve "RangeCrror no capturado: se excedió el tamaño máximo de pila de llamadas (...)" en var byteArray = new Uint8Array (bytes_needed); ¿Qué podría ser un problema?
    2016-04-06 08: 35: 33Z
  5. Ediciones incorrectas en el pasado, deberían ser buenas ahora.
    2016-04-11 13: 51: 34Z

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

 _cryptoGuid

Aquí hay una muestra de los UUID generados:

 _guid     
23
2009-08-24 16: 12: 46Z

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 http://www.ietf.org/rfc/rfc4122.txt .

     

Características Genera UUID compatibles con RFC 4122.

     

UUID de la versión 4 (UUID de números aleatorios) y 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 al azar   números.

    
23
2012-07-02 21: 00: 32Z
 
  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 <baagoe@baagoe.com>, 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 <baagoe@baagoe.com>, 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);
  });
};
    
16
2010-07-14 23: 30: 52Z
  1. Me gusta este enfoque, pero ten en cuenta que no funciona correctamente en Chrome. La parte ".slice (2, 14)" solo devuelve 8 caracteres, no 12.
    2011-09-14 20: 37: 43Z

Ajusté mi propio generador UUID /GUIDcon algunos extras aquí .

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.

 rval = rval & mask     
13
2012-01-13 21: 59: 35Z

La mejor manera:

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

Minimizado:

 
682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136
    
12
2012-05-23 18: 42: 35Z

Quería entender la respuesta de Broofa, así que la amplié y agregué comentarios:

 
  // 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('-');
    
12
2017-02-20 14: 46: 21Z

muestra ES6

 
//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 <baagoe@baagoe.com>, 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));
    
12
2017-07-09 13: 01: 53Z

Es solo una simple llamada AJAX ...

Si alguien está interesado, aquí está mi solución.

En el lado del servidor:

 
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
 }

En el lado del cliente:

 
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}
    
11
2010-02-05 03: 23: 46Z
  1. Su método es la única forma correcta, pero el problema es que es asíncrono, por lo que realmente no puede usarlo. Además, intente hacer eso unas 100 a 1000 veces y bloqueará IE (aunque no Chrome y Firefox). Necesitaríamos llamadas sincrónicas: ¡Use JQuery, no JavaScript de MS-PageMethod!
    2010-03-30 11: 46: 04Z
  2. Tienes razón, se llama asincrónicamente, esto no es muy útil. Irónicamente, mi código original usa jQuery para invocar este método de forma sincrónica. Aquí hay un ejemplo: $.ajax ({async: false, escriba: 'POST', url: 'MyPage.aspx /GenerateGuid', contentType: 'application /json; charset = utf-8', data: '{}', success: function (data) {//data contiene su nuevo GUID}, failure: function (msg) {alert (msg);}});
    2010-04-05 23: 26: 44Z
  3. ¿Por qué necesita hacer una llamada AJAX si está utilizando ASP.NET? Solo haga <% = Guid.NewGuid (). ToString ()% > en aspx.
    2012-01-26 01: 02: 13Z
  4. @ kape123: Eso está bien, si solo quieres un GUID. El servicio web le permite generar múltiples GUID sin volver a cargar la página.
    2013-07-23 01: 20: 36Z

Para aquellos que desean una solución compatible con la versión 4 de rfc4122 con consideraciones de velocidad (pocas llamadas a Math.random ()):

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

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

    
11
2012-11-16 19: 41: 49Z

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

uid-139410573297741

 
const guid=()=> {
  const s4=()=> Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);     
  return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
}
    
11
2014-03-06 11: 34: 54Z

Lo sé, es una vieja pregunta. Solo para estar completo, si su entorno es SharePoint, hay una función de utilidad llamada

[WebMethod()]
public static string GenerateGuid()
{
    return Guid.NewGuid().ToString();
}
( msdn link ) que crea un nuevo guid. 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 myNewGuid = null;
PageMethods.GenerateGuid(
    function(result, userContext, methodName)
    {
        myNewGuid = result;
    },
    function()
    {
        alert("WebService call failed.");
    }
);
    
10
2013-06-12 16: 00: 03Z

Hay un complemento de jQuery que maneja muy bien Guid's @ http://plugins.jquery.com/project/GUID_Helper

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

Devuelve el valor de Guid interno. Si no se ha especificado ningún guid, devuelve uno nuevo (el valor se almacena internamente).


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

Devuelve un nuevo Guid y establece su valor internamente.


 SP.Guid.newGuid

Devuelve un Guid 00000000-0000-0000-0000-000000000000 vacío.


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

Devuelve booleano. Verdadero si está vacío /indefinido /en blanco /nulo.


 
jQuery.Guid.Value()

Devuelve booleano. Verdadero guid válido, falso si no.


 
jQuery.Guid.New()

Retrns Guid. Establece Guid en Guid especificado por el usuario, si no es válido, devuelve un guid vacío.     

10
2013-10-09 04: 54: 35Z
  1. El enlace al complemento está roto
    2017-05-18 08: 08: 15Z

Código simple que usa

jQuery.Guid.Empty()
en navegadores compatibles (IE11 +, iOS7 +, FF21 +, Chrome, Android Chrome ). Evita el uso de
jQuery.Guid.IsEmpty()
porque puede causar colisiones (por ejemplo, 20 colisiones para 4000 uuids generados en una situación real por Muxa ).  
jQuery.Guid.IsValid()

Notas:

  • Optimizado para la legibilidad del código, no la velocidad, por lo que es adecuado para, por ejemplo, unos cientos de uuid por segundo. Genera aproximadamente 10000 uuid () por segundo en Chromium en mi computadora portátil utilizando http://jsbin.com/fuwigo/1 para medir el rendimiento.
  • Solo usa 8 para "y" porque eso simplifica la legibilidad del código (y se permite que sea 8, 9, A o B).
9
2017-05-23 11: 47: 36Z
  1. jsfiddle.net/of3v5zko Jsfiddle que utiliza API crypto para generar un UUID, compatible con RFC4122 versión 4 Fuente original github. com /Chalarangelo /30-seconds-of-code # uuid-generator
    2017-12-14 09: 12: 43Z
  2. @ ananda Gracias. Sin embargo, el código no es compatible con los navegadores existentes. Además, aunque ese código guarda algunos bytes, creo que es menos legible (me gusta que mi código sea claro) y es bastante posible que después de que uglifier y gzipping su versión no guarden nada (una serie de
    jQuery.Guid.Set()
    
    caracteres e identificadores comunes se comprimen muy bien) . - robocat hace 8 minutos
    2018-03-11 22: 48: 58Z
crypto.getRandomValues(a)
fuente colocada aquí