react generate javascript guid uuid

javascript - generate - uuid npm



Crear GUID/UUID en JavaScript? (30)

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 implementación totalmente no compatible pero muy eficaz para generar un identificador único de tipo GUID seguro para ASCII.

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

Genera 26 caracteres [a-z0-9], lo que produce 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.

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

Aquí está el código de tiempo.

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


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.


El GUID más rápido como método generador de cadenas en el formato XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX . Esto no genera GUID compatible con el estándar.

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:

/** * Generates a GUID string. * @returns {String} The generated GUID. * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa * @author Slavik Meltser ([email protected]). * @link http://slavik.meltser.info/?p=142 */ function guid() { function _p8(s) { var p = (Math.random().toString(16)+"000000000").substr(2,8); return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ; } return _p8() + _p8(true) + _p8(true) + _p8(); }

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

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

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

El algoritmo:

  • La función Math.random() devuelve un número decimal entre 0 y 1 con 16 dígitos después del punto de fracción decimal (por ejemplo, 0.4363923368509859 ).
  • Luego tomamos este número y lo convertimos en una cadena con base 16 (del ejemplo anterior obtendremos 0.6fb7687f ).
    Math.random().toString(16) .
  • Luego cortamos el prefijo 0. ( 0.6fb7687f => 6fb7687f ) y obtenemos una cadena con ocho caracteres hexadecimales.
    (Math.random().toString(16).substr(2,8) .
  • A veces, la función Math.random() devolverá un número más corto (por ejemplo, 0.4363 ), debido a los ceros al final (del ejemplo anterior, en realidad el número es 0.4363000000000000 ). Es por eso que estoy agregando a esta cadena "000000000" (una cadena con nueve ceros) y luego cortándola con la función substr() para que tenga nueve caracteres exactamente (rellene los ceros a la derecha).
  • La razón para agregar exactamente nueve ceros es debido al peor escenario, que es cuando la función Math.random() devolverá exactamente 0 o 1 (probabilidad de 1/10 ^ 16 para cada uno de ellos). Por eso necesitamos agregar nueve ceros ( "0"+"000000000" o "1"+"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 lo está cortando.
    Math.random().toString(16)+"000000000").substr(2,8) .

La Asamblea:

  • El GUID está en el siguiente formato XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX .
  • Dividí el GUID en 4 piezas, cada pieza dividida en 2 tipos (o formatos): XXXXXXXX y -XXXX-XXXX .
  • Ahora estoy creando el GUID utilizando estos 2 tipos para ensamblar el GUID con 4 piezas de llamada, de la siguiente manera: XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX .
  • Para diferenciar entre estos dos tipos, agregué un parámetro de _p8(s) a una función de creador de pares _p8(s) , el parámetro s le dice a la función si agregar o no guiones.
  • Finalmente, construimos el GUID con el siguiente encadenamiento: _p8() + _p8(true) + _p8(true) + _p8() , y lo devolvemos.

Enlace a esta publicación en mi blog

¡Disfrutar! :-)


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.


Para una solución compatible con la versión 4 de RFC4122 , esta solución de una sola línea (ish) es la más compacta que puedo 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 se garantiza que sea un RNG de alta calidad. Vea el excelente artículo de Adam Hyland en Math.random () para más detalles. 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 : Un buen artículo de los desarrolladores de Chrome sobre el estado de la calidad de Math.random PRNG 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, la API crypto y un poco de JS wizardy. No puedo reconocer nada :

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


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.


Es solo una simple llamada AJAX ...

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

En el lado del servidor:

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

En el lado del cliente:

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


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}


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

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

Uso:

Guid.newGuid ()

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

Guid.empty

"00000000-0000-0000-0000-000000000000"


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.


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

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


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


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

Parece bastante elegante, y tal vez podría mejorarse compartiendo con un hash de la dirección IP del cliente. Este hash tal vez 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 tenido un orden aleatorio, aquí está la versión actualizada


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


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

jQuery.Guid.Value()

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

jQuery.Guid.New()

Devuelve un nuevo Guid y establece su valor internamente.

jQuery.Guid.Empty()

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

jQuery.Guid.IsEmpty()

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

jQuery.Guid.IsValid()

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

jQuery.Guid.Set()

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


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.


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

Generación simple y rápida de ietf.org/rfc/rfc4122.txt UUIDS.

caracteristicas:

  • Genere los UUIDs 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? ¡ https://gist.github.com/982883 )

Instalar utilizando NPM:

npm install uuid

O usando uuid a través del navegador:

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

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

Uso:

// Generate a v1 UUID (time-based) const uuidV1 = require(''uuid/v1''); uuidV1(); // -> ''6c84fb90-12c4-11e1-840d-7b25c5ee775a'' // Generate a v4 UUID (random) const uuidV4 = require(''uuid/v4''); uuidV4(); // -> ''110ec58a-a0f2-4ac4-8393-c866d813b8d1'' // Generate a v5 UUID (namespace) const uuidV5 = require(''uuid/v5''); // ... using predefined DNS namespace (for domain names) uuidV5(''hello.example.com'', v5.DNS)); // -> ''fdda765f-fc57-5604-a269-52a7df8164ec'' // ... using predefined URL namespace (for, well, URLs) uuidV5(''http://example.com/hello'', v5.URL); // -> ''3bbcee75-cecc-5b56-8031-b6641c1ed1f1'' // ... using a custom namespace const MY_NAMESPACE = ''(previously generated unique uuid string)''; uuidV5(''hello'', MY_NAMESPACE); // -> ''90123e1c-7512-523e-bb28-76fab9f2f73d''

ES6:

import uuid from ''uuid/v4''; const id = uuid();


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


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

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