guid - uuid npm
¿Qué tan único es UUID? (10)
Aquí hay un fragmento de prueba para que pruebes sus exclusiones. inspirado en el comentario de @ scalabl3
Lo curioso es que podría generar 2 en una fila que eran idénticos, por supuesto en niveles de coincidencia, suerte e intervención divina alucinantes, pero a pesar de las probabilidades insondables, ¡todavía es posible! : D Sí, no va a pasar. ¡Solo digo por la diversión de pensar en ese momento cuando creaste un duplicado! Captura de pantalla del video! - Scalabl3 20 de octubre de 15 a 19:11
Si te sientes con suerte, marca la casilla de verificación, solo verifica los ID generados actualmente. Si desea una verificación de historial, déjela sin marcar. Tenga en cuenta que puede quedarse sin RAM en algún momento si lo deja sin marcar. Traté de hacer que la CPU sea amigable para que pueda abortar rápidamente cuando sea necesario, simplemente presione el botón Ejecutar fragmento de código de nuevo o salga de la página.
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);
});
};
function logit(item1, item2) {
console.log("Do "+item1+" and "+item2+" equal? "+(item1 == item2 ? "OMG! take a screenshot and you''ll be epic on the world of cryptography, buy a lottery ticket now!":"No they do not. shame. no fame")+ ", runs: "+window.numberofRuns);
}
numberofRuns = 0;
function test() {
window.numberofRuns++;
var x = Math.guid();
var y = Math.guid();
var test = x == y || historyTest(x,y);
logit(x,y);
return test;
}
historyArr = [];
historyCount = 0;
function historyTest(item1, item2) {
if(window.luckyDog) {
return false;
}
for(var i = historyCount; i > -1; i--) {
logit(item1,window.historyArr[i]);
if(item1 == history[i]) {
return true;
}
logit(item2,window.historyArr[i]);
if(item2 == history[i]) {
return true;
}
}
window.historyArr.push(item1);
window.historyArr.push(item2);
window.historyCount+=2;
return false;
}
luckyDog = false;
document.body.onload = function() {
document.getElementById(''runit'').onclick = function() {
window.luckyDog = document.getElementById(''lucky'').checked;
var val = document.getElementById(''input'').value
if(val.trim() == ''0'') {
var intervaltimer = window.setInterval(function() {
var test = window.test();
if(test) {
window.clearInterval(intervaltimer);
}
},0);
}
else {
var num = parseInt(val);
if(num > 0) {
var intervaltimer = window.setInterval(function() {
var test = window.test();
num--;
if(num < 0 || test) {
window.clearInterval(intervaltimer);
}
},0);
}
}
};
};
Please input how often the calulation should run. set to 0 for forever. Check the checkbox if you feel lucky.<BR/>
<input type="text" value="0" id="input"><input type="checkbox" id="lucky"><button id="runit">Run</button><BR/>
¿Qué tan seguro es usar UUID para identificar algo de manera única (lo estoy usando para los archivos cargados en el servidor)? Como yo lo entiendo, se basa en números aleatorios. Sin embargo, me parece que si se le da suficiente tiempo, eventualmente se repetirá, solo por pura casualidad. ¿Hay un mejor sistema o un patrón de algún tipo para aliviar este problema?
Citando de Wikipedia :
Por lo tanto, cualquier persona puede crear un UUID y usarlo para identificar algo con la confianza razonable de que el identificador nunca será utilizado involuntariamente por nadie para nada más.
Continúa explicando con bastante detalle qué tan seguro es realmente. Entonces, para responder a tu pregunta: Sí, es lo suficientemente seguro.
Coincido con las otras respuestas. Los UUID son lo suficientemente seguros para casi todos los propósitos prácticos 1 , y ciertamente para los suyos.
Pero supongamos (hipotéticamente) que no lo son.
¿Hay un mejor sistema o un patrón de algún tipo para aliviar este problema?
Aquí hay un par de enfoques:
Use un UUID más grande. Por ejemplo, en lugar de 128 bits aleatorios, use 256 o 512 o ... Cada bit que agregue a un UUID de estilo tipo 4 reducirá la probabilidad de una colisión a la mitad, suponiendo que tenga una fuente confiable de entropía 2 .
Cree un servicio centralizado o distribuido que genere UUID y registre todos y cada uno de los problemas que emita. Cada vez que genera uno nuevo, verifica que el UUID nunca se haya emitido antes. Tal servicio sería técnicamente sencillo de implementar (creo) si asumiéramos que las personas que dirigían el servicio eran absolutamente confiables, incorruptibles, etc. Desafortunadamente, no lo son ... especialmente cuando existe la posibilidad de que los gobiernos interfieran. Por lo tanto, este enfoque es probablemente poco práctico y puede ser imposible en el mundo real.
1 - Si la singularidad de los UUID determinara si los misiles nucleares se lanzaron a la capital de su país, muchos de sus conciudadanos no se convencerían de que "la probabilidad es extremadamente baja". De ahí mi calificación de "casi todos".
2 - Y aquí hay una pregunta filosófica para ti. ¿Hay algo realmente aleatorio? ¿Cómo sabríamos si no lo fuera? ¿Es el universo como lo conocemos una simulación? ¿Existe un Dios que podría "modificar" las leyes de la física para alterar un resultado?
3 - Si alguien sabe de algún trabajo de investigación sobre este problema, por favor comente.
Hay más de un tipo de UUID, por lo que "qué tan seguro" depende de qué tipo (que las especificaciones UUID llaman "versión") está usando.
La versión 1 es el UUID basado en el tiempo más la dirección MAC. Los 128 bits contienen 48 bits para la dirección MAC de la tarjeta de red (asignada de forma única por el fabricante) y un reloj de 60 bits con una resolución de 100 nanosegundos. Ese reloj se ajusta al 3603 AD para que estos UUID estén seguros al menos hasta entonces (a menos que necesite más de 10 millones de UUID nuevos por segundo o alguien clone su tarjeta de red). Digo "al menos" porque el reloj comienza a partir del 15 de octubre de 1582, por lo que tiene aproximadamente 400 años después de que se cierre el reloj antes de que haya incluso una pequeña posibilidad de duplicación.
La versión 4 es el número aleatorio UUID. Hay seis bits fijos y el resto del UUID es 122 bits de aleatoriedad. Ver Wikipedia u otro análisis que describa cuán improbable es un duplicado.
La versión 3 usa MD5 y la versión 5 usa SHA-1 para crear esos 122 bits, en lugar de un generador de números aleatorios o pseudoaleatorios. Por lo tanto, en términos de seguridad, es como si la Versión 4 fuera un problema estadístico (siempre que se asegure de que el algoritmo de resumen está procesando es siempre único).
La versión 2 es similar a la versión 1, pero con un reloj más pequeño, por lo que se cerrará mucho antes. Pero como los UUID de la Versión 2 son para DCE, no debería usarlos.
Así que para todos los problemas prácticos son seguros. Si no te sientes cómodo con dejarlo a las probabilidades (por ejemplo, eres el tipo de persona preocupada por la destrucción de la tierra por un gran asteroide en tu vida), asegúrate de usar un UUID de la Versión 1 y se garantiza que es único ( en su vida, a menos que planee vivir más allá del 3603 dC).
Entonces, ¿por qué no todos simplemente usan UUID de la Versión 1? Esto se debe a que los UUID de la Versión 1 revelan la dirección MAC de la máquina en la que se generó y pueden ser predecibles, dos cosas que podrían tener implicaciones de seguridad para la aplicación que utiliza esos UUID.
La respuesta a esto puede depender en gran medida de la versión UUID.
Muchos generadores UUID usan un número aleatorio de la versión 4. Sin embargo, muchos de estos utilizan Pseudo un generador de números aleatorios para generarlos.
Si se utiliza un PRNG mal sembrado con un período pequeño para generar el UUID, diría que no es muy seguro en absoluto.
Por lo tanto, es tan seguro como los algoritmos utilizados para generarlo.
Por otro lado, si conoce la respuesta a estas preguntas, creo que una versión 4 uuid debería ser muy segura de usar. De hecho, lo estoy usando para identificar bloques en un sistema de archivos de bloque de red y hasta ahora no he tenido un choque.
En mi caso, el PRNG que estoy usando es un tornado mersenne y estoy teniendo cuidado con la forma en que se siembra, que proviene de múltiples fuentes, incluyendo / dev / urandom. Mersenne twister tiene un período de 2 ^ 19937 - 1. Pasará un tiempo muy largo antes de que vea un uuid repetido.
Lo he estado haciendo durante años. Nunca se tope con un problema.
Por lo general, configuro mis DB para tener una tabla que contenga todas las claves y las fechas modificadas y demás. No me he encontrado con un problema de claves duplicadas nunca.
El único inconveniente que tiene es que cuando escribe algunas consultas para encontrar información rápidamente, está copiando y pegando muchas claves. Ya no tienes los identificadores cortos fáciles de recordar.
Los esquemas UUID generalmente usan no solo un elemento pseudoaleatorio, sino también la hora actual del sistema y algún tipo de ID de hardware a menudo único, si está disponible, como una dirección MAC de red.
El punto central del uso de UUID es que confías en que haga un mejor trabajo para proporcionar una identificación única de la que tú mismo podrías hacer. Esta es la misma razón detrás del uso de una biblioteca de criptografía de terceros en lugar de rodar la suya propia. Hacerlo usted mismo puede ser más divertido, pero generalmente es menos responsable hacerlo.
Muy seguro:
el riesgo anual de que una persona determinada sea alcanzada por un meteorito se estima que es una posibilidad entre 17 mil millones, lo que significa que la probabilidad es de aproximadamente 0.00000000006 (6 × 10-11 ), equivalente a la probabilidad de crear unas decenas de billones de UUID en un año y teniendo un duplicado. En otras palabras, solo después de generar 1 mil millones de UUID por segundo durante los próximos 100 años, la probabilidad de crear un solo duplicado sería aproximadamente del 50%.
Advertencia:
Sin embargo, estas probabilidades solo se mantienen cuando los UUID se generan utilizando suficiente entropía. De lo contrario, la probabilidad de duplicados podría ser significativamente mayor, ya que la dispersión estadística podría ser menor. Cuando se requieren identificadores únicos para las aplicaciones distribuidas, para que los UUID no entren en conflicto, incluso cuando se combinan los datos de muchos dispositivos, la aleatoriedad de las semillas y los generadores utilizados en cada dispositivo debe ser confiable durante la vida de la aplicación. Cuando esto no sea factible, RFC4122 recomienda usar una variante de espacio de nombres en su lugar.
Fuente: La sección de probabilidad de duplicados de UUID aleatorios del artículo de Wikipedia sobre identificadores únicos universales (el enlace conduce a una revisión de diciembre de 2016 antes de editar la sección reelaborada).
Consulte también la sección actual sobre el mismo tema en el mismo artículo de identificador único universal, Collisions .
No sé si esto es importante para usted, pero tenga en cuenta que los GUID son únicos a nivel mundial, pero las subcadenas de los GUID no lo son .
Si por "tiempo suficiente" quiere decir 100 años y los está creando a una velocidad de mil millones por segundo, entonces sí, tiene un 50% de probabilidades de sufrir una colisión después de 100 años.