¿Cadena alfanumérica aleatoria en JavaScript?

Resuelto Pavel asked hace 12 años • 24 respuestas

¿Cuál es la forma más corta (dentro de lo razonable) de generar una cadena alfanumérica aleatoria (mayúsculas, minúsculas y números) en JavaScript para usarla como un identificador probablemente único?

Pavel avatar May 24 '12 02:05 Pavel
Aceptado

Me pareció una solución realmente agradable y elegante:

Math.random().toString(36).slice(2)

Notas sobre esta implementación:

  • Esto producirá una cadena de entre cero y 12 caracteres de largo, generalmente 11 caracteres, debido al hecho de que la cadena de punto flotante elimina los ceros finales.
  • No generará letras mayúsculas, sólo minúsculas y números.
  • Debido a que la aleatoriedad proviene de Math.random(), el resultado puede ser predecible y, por lo tanto, no necesariamente único.
  • Incluso suponiendo una implementación ideal, la salida tiene como máximo 52 bits de entropía, lo que significa que puede esperar un duplicado después de generar alrededor de 70 millones de cadenas.
JAR.JAR.beans avatar Sep 19 '2012 20:09 JAR.JAR.beans

Si solo quieres permitir caracteres específicos, también puedes hacerlo así:

function randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
    return result;
}
var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

Aquí hay un jsfiddle para demostrar: http://jsfiddle.net/wSQBx/

Otra forma de hacerlo podría ser utilizar una cadena especial que le indique a la función qué tipos de caracteres utilizar. Podrías hacerlo así:

function randomString(length, chars) {
    var mask = '';
    if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
    if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    if (chars.indexOf('#') > -1) mask += '0123456789';
    if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
    var result = '';
    for (var i = length; i > 0; --i) result += mask[Math.floor(Math.random() * mask.length)];
    return result;
}

console.log(randomString(16, 'aA'));
console.log(randomString(32, '#aA'));
console.log(randomString(64, '#A!'));

Violín: http://jsfiddle.net/wSQBx/2/

Alternativamente, para utilizar el método base36 como se describe a continuación, puede hacer algo como esto:

function randomString(length) {
    return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
Nimphious avatar May 23 '2012 20:05 Nimphious

ACTUALIZADO: Solución de una sola línea, para 20 caracteres aleatorios (minúsculas alfanuméricas):

Array.from(Array(20), () => Math.floor(Math.random() * 36).toString(36)).join('');

O más corto con lodash:

_.times(20, () => _.random(35).toString(36)).join('');
DS. avatar Jun 19 '2017 04:06 DS.

Otra variación de respuesta sugerida por JAR.JAR.beans

(Math.random()*1e32).toString(36)

Al cambiar el multiplicador 1e32puedes cambiar la longitud de una cadena aleatoria.

he-yaeh avatar Jun 18 '2015 20:06 he-yaeh