Generar cadenas/caracteres aleatorios en JavaScript
Quiero una cadena de 5 caracteres compuesta de caracteres elegidos al azar del conjunto [a-zA-Z0-9]
.
¿Cuál es la mejor manera de hacer esto con JavaScript?
Creo que esto funcionará para ti:
function makeid(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
}
console.log(makeid(5));
//Can change 7 to 2 for longer results.
let r = (Math.random() + 1).toString(36).substring(7);
console.log("random", r);
Nota: El algoritmo anterior tiene las siguientes debilidades:
- Generará entre 0 y 6 caracteres debido al hecho de que los ceros finales se eliminan al encadenar puntos flotantes.
- Depende profundamente del algoritmo utilizado para encadenar números de coma flotante, que es terriblemente complejo. (Consulte el artículo "Cómo imprimir números de punto flotante con precisión" .)
Math.random()
puede producir resultados predecibles ("de apariencia aleatoria", pero no realmente aleatorios) dependiendo de la implementación. La cadena resultante no es adecuada cuando es necesario garantizar la unicidad o la imprevisibilidad.- Incluso si produjera 6 caracteres uniformemente aleatorios e impredecibles, puede esperar ver un duplicado después de generar solo unas 50.000 cadenas, debido a la paradoja del cumpleaños . (cuadrado(36^6) = 46656)
Math.random es malo para este tipo de cosas
lado del servidor
Utilice el módulo criptográfico de nodo -
var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');
// "bb5dc8842ca31d4603d6aa11448d1654"
La cadena resultante será el doble de larga que los bytes aleatorios que generes; cada byte codificado en hexadecimal tiene 2 caracteres. 20 bytes serán 40 caracteres hexadecimales.
lado del cliente
Utilice el módulo criptográfico del navegador, crypto.getRandomValues -
El
crypto.getRandomValues()
método le permite obtener valores aleatorios criptográficamente fuertes. La matriz dada como parámetro se llena con números aleatorios (aleatorios en su significado criptográfico).
// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
function dec2hex (dec) {
return dec.toString(16).padStart(2, "0")
}
// generateId :: Integer -> String
function generateId (len) {
var arr = new Uint8Array((len || 40) / 2)
window.crypto.getRandomValues(arr)
return Array.from(arr, dec2hex).join('')
}
console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"
console.log(generateId(20))
// "c1a050a4cd1556948d41"
Un ejemplo de consola paso a paso:
> var arr = new Uint8Array(4) # make array of 4 bytes (values 0-255)
> arr
Uint8Array(4) [ 0, 0, 0, 0 ]
> window.crypto
Crypto { subtle: SubtleCrypto }
> window.crypto.getRandomValues()
TypeError: Crypto.getRandomValues requires at least 1 argument, but only 0 were passed
> window.crypto.getRandomValues(arr)
Uint8Array(4) [ 235, 229, 94, 228 ]
Para compatibilidad con IE11, puede utilizar:
(window.crypto || window.msCrypto).getRandomValues(arr)
Para conocer la cobertura del navegador, consulte https://caniuse.com/#feat=getrandomvalues
lado del cliente (navegadores antiguos)
Si debe admitir navegadores antiguos, considere algo como uuid
:
const uuid = require("uuid");
const id = uuid.v4();
// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"
Corto, fácil y confiable
Devuelve exactamente 5 caracteres aleatorios, a diferencia de algunas de las respuestas mejor calificadas que se encuentran aquí.
Math.random().toString(36).slice(2, 7);