Genere cadenas / caracteres aleatorios en JavaScript

Quiero una cadena de 5 caracteres compuesta por caracteres seleccionados al azar del conjunto. [a-zA-Z0-9].

¿Cuál es la mejor manera de hacer esto con JavaScript?

preguntado el 28 de agosto de 09 a las 18:08

Advertencia: Ninguna de las respuestas tiene true-random ¡resultado! Son solo pseudo-random. Cuando use cadenas aleatorias para protección o seguridad, ¡no use ninguna de ellas! Prueba una de estas api: Random.org -

Math.random (). ToString (36) .replace (/ [^ az] + / g, '') -

Pon la solución en una solución. -

Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); -

Nota API de aleatoriedad de cifrado web HTML5 proporciona aleatoriedad real. -

30 Respuestas

Creo que esto funcionará para ti:

function makeid(length) {
   var result           = '';
   var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
   var charactersLength = characters.length;
   for ( var i = 0; i < length; i++ ) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
   }
   return result;
}

console.log(makeid(5));

Respondido 23 Abr '19, 23:04

Esto está bien para cadenas cortas, pero tenga cuidado, use += en cadenas como esta hace que tenga un comportamiento O (n ^ 2). Si desea crear cadenas más largas, debe crear una matriz de caracteres individuales y unirlos al final. - dan_waterworth

@dan_waterworth Probablemente no importe en casi cualquier caso: codificaciónhorror.com/blog/2009/01/… - alex reece

@dan_waterworth, en realidad, += es a menudo más rápido por alguna razón, incluso se usa dentro de bucles - jsperf.com/join-vs-concatenation - Konrad Borowski

@JonathanPaulson Muéstrame los números. Vea el comentario anterior con un enlace jsperf o jsperf.com/sad-tragedy-of-microoptimization or sitepen.com/blog/2008/05/09/string-performance-an-analysis etc. Además, esta pregunta implica solo 5 concatenaciones. - alex reece

@codenamejames Por favor No tienes que proporcionar información médica privada para contar tu caso. Simplemente envíanos un breve resumen de lo que sucedió. use esto en la salazón de su contraseña. Es solo pseudoaleatorio, no seguro. Suponiendo que está usando Node (ni siquiera estoy seguro de por dónde empezar si está salando en el lado del cliente), use crypto en lugar de. - Hidrotermal

let r = Math.random().toString(36).substring(7);
console.log("random", r);

Nota: El algoritmo anterior tiene las siguientes debilidades:

  • Generará en cualquier lugar entre 0 y 6 caracteres debido al hecho de que los ceros finales se eliminan al encadenar puntos flotantes.
  • Depende en gran medida del algoritmo utilizado para clasificar los números de punto flotante, que es horriblemente complejo. (Ver el papel "Cómo imprimir números de punto flotante con precisión".)
  • Math.random() puede producir una salida predecible ("de apariencia aleatoria" pero no realmente aleatoria) dependiendo de la implementación. La cadena resultante no es adecuada cuando necesita garantizar la singularidad o la imprevisibilidad.
  • Incluso si produjo 6 caracteres impredecibles uniformemente aleatorios, puede esperar ver un duplicado después de generar solo alrededor de 50,000 cadenas, debido a la paradoja de cumpleaños. (raíz cuadrada de (36 ^ 6) = 46656)

Respondido 05 Feb 19, 17:02

Math.random().toString(36).substr(2, 5), porque .substring(7) hace que tenga más de 5 caracteres. ¡Puntos completos, todavía! - dragón

@Scoop El toString El método de un tipo de número en javascript toma un parámetro opcional para convertir el número en una base determinada. Si pasa dos, por ejemplo, verá su número representado en binario. Similar al hexadecimal (base 16), la base 36 usa letras para representar dígitos más allá del 9. Al convertir un número aleatorio en base 36, terminará con un montón de letras y números aparentemente aleatorios. - Chris Baker

¡Se ve hermoso pero en algunos casos esto genera una cadena vacía! Si aleatorio devuelve 0, 0.5, 0.25, 0.125 ... resultará en una cadena vacía o corta. - Gertas

@gertas Esto se puede evitar (Math.random() + 1).toString(36).substring(7); - Jorge Reith

Chico, esto es virtualmente inútil. Ejecútelo solo 1000000 veces y generalmente obtendrá alrededor de 110000 repeticiones: var values ​​= {}, i = 0, duplicateCount = 0, val; while (i <1000000) {val = Math.random (). toString (36) .substring (7); if (valores [val]) {duplicateCount ++; } valores [val] = 1; i ++; } console.log ("DUPLICADOS TOTALES", duplicateCount); - hacklikecrack

matemáticas.al azar es malo para este tipo de cosas

Opción 1

Si eres capaz de hacer esto servidor-side, solo usa el cripto módulo -

var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

// "bb5dc8842ca31d4603d6aa11448d1654"

La cadena resultante tendrá el doble de longitud que los bytes aleatorios que genere; cada byte codificado en hexadecimal tiene 2 caracteres. 20 bytes serán 40 caracteres hexadecimales.


Opción 2

Si tienes que hacer esto cliente-side, quizás pruebe el módulo uuid -

var uuid = require("uuid");
var id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

Opción 3

Si tienes que hacer esto cliente-side y no tiene que admitir navegadores antiguos, puede hacerlo sin dependencias -

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


Para obtener más información sobre crypto.getRandomValues -

LA crypto.getRandomValues() El método le permite obtener valores aleatorios criptográficamente fuertes. La matriz dada como parámetro está llena de números aleatorios (aleatorios en su significado criptográfico).

Aquí hay un pequeño ejemplo de consola:

> 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 el soporte de IE11, puede usar:

(window.crypto || window.msCrypto).getRandomValues(arr)

Para conocer la cobertura del navegador, consulte https://caniuse.com/#feat=getrandomvalues

Respondido el 01 de diciembre de 20 a las 17:12

Exactamente. Si bien un UUID está bien para asignar una ID a algo, usarlo como una cadena de caracteres aleatorios no es una gran idea por esta (y probablemente otras) razones. - wmassingham

No hay necesidad de .map() en la Opción 3. Array.from(arr, dec2hex).join('') === Array.from(arr).map(dec2hex).join(''). Gracias por presentarme estas funciones :-) - Fred Gandt

Debe mencionar en la respuesta que la opción 2 también necesita node.js para funcionar, no es javascript puro. - Esko

Si bien es más seguro criptográficamente, esto en realidad no satisface los requisitos de la pregunta porque solo genera 0-9 y af (hexadecimal), y no 0-9, az, AZ. - jake

@ AneesAhmed777 el dec2hex se le proporcionó un codificador de ejemplo. Depende de usted representar los bytes como elija. Actualicé la publicación con tu sugerencia. - Gracias

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).substr(2, 5);

Respondido el 12 de diciembre de 17 a las 10:12

Y si Math.random().toString(36) devuelve un número con menos de 5 caracteres? - Michael Litvin

Bueno, esa es una acusación interesante de @ Aperçu, no estoy diciendo que inventé la solución, pero la he estado usando en mis proyectos durante años. Y no tiene nada que ver con el comentario que mencionaste. Y estoy bastante seguro de que en SO lo que importa es la información más útil en el lugar correcto e incluso si ya existe en algún otro lugar también. Afortunadamente, parece que al menos 51 chicos han encontrado útil esta respuesta, ¡de nada! - Ringvee de plata

@rinogo Math.random () puede devolver 0 pero no 1 desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Mikep

Ejecuté este código 1,000,000,000 veces y todavía no obtuve una cadena vacía: jsfiddle.net/mtp5730r Diría que está bastante a salvo de obtener una cadena vacía. - macrohombre

Un evento que sea estadísticamente improbable no lo hace seguro. Si alguien está usando esto para cualquier actividad relacionada con la seguridad, está apostando a la improbabilidad de Math.random no devuelve 0. Espero que nunca tengas que depurar este evento - Purefán

Aquí hay una mejora en la excelente respuesta de doubletap. El original tiene dos inconvenientes que se tratan aquí:

Primero, como han mencionado otros, tiene una pequeña probabilidad de producir cadenas cortas o incluso una cadena vacía (si el número aleatorio es 0), lo que puede romper su aplicación. He aquí una solución:

(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

En segundo lugar, tanto el original como la solución anterior limitan el tamaño de la cadena N a 16 caracteres. Lo siguiente devolverá una cadena de tamaño N para cualquier N (pero tenga en cuenta que el uso de N> 16 no aumentará la aleatoriedad ni disminuirá la probabilidad de colisiones):

Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

Explicación:

  1. Elija un número aleatorio en el rango [0,1), es decir, entre 0 (inclusive) y 1 (exclusivo).
  2. Convierta el número a una cadena de base 36, es decir, utilizando los caracteres 0-9 y az.
  3. Rellenar con ceros (resuelve el primer problema).
  4. Corta el '0' inicial. prefijo y ceros de relleno adicionales.
  5. Repita la cadena suficientes veces para tener al menos N caracteres en ella (uniendo cadenas vacías con la cadena aleatoria más corta utilizada como delimitador).
  6. Corta exactamente N caracteres de la cadena.

Pensamientos adicionales:

  • Esta solución no usa letras mayúsculas, pero en casi todos los casos (sin juego de palabras) no importa.
  • La longitud máxima de la cadena en N = 16 en la respuesta original se mide en Chrome. En Firefox es N = 11. Pero como se explicó, la segunda solución consiste en admitir cualquier longitud de cadena solicitada, no en agregar aleatoriedad, por lo que no hace mucha diferencia.
  • Todas las cadenas devueltas tienen la misma probabilidad de ser devueltas, al menos en la medida en que los resultados devueltos por Math.random () estén distribuidos uniformemente (esto no es una aleatoriedad de fuerza criptográfica, en cualquier caso).
  • Es posible que no se devuelvan todas las cadenas posibles de tamaño N. En la segunda solución, esto es obvio (ya que la cadena más pequeña simplemente se está duplicando), pero también en la respuesta original esto es cierto ya que en la conversión a base-36 los últimos bits pueden no ser parte de los bits aleatorios originales. Específicamente, si observa el resultado de Math.random (). ToString (36), notará que el último carácter no está distribuido uniformemente. Nuevamente, en casi todos los casos no importa, pero cortamos la cadena final desde el principio en lugar del final de la cadena aleatoria para que las cadenas cortas (por ejemplo, N = 1) no se vean afectadas.

Actualizar:

Aquí hay un par de frases ingeniosas de estilo funcional que se me ocurrieron. Se diferencian de la solución anterior en que:

  • Usan un alfabeto arbitrario explícito (más genérico y adecuado a la pregunta original que pedía letras mayúsculas y minúsculas).
  • Todas las cadenas de longitud N tienen la misma probabilidad de ser devueltas (es decir, las cadenas no contienen repeticiones).
  • Se basan en una función de mapa, en lugar del truco toString (36), lo que los hace más sencillos y fáciles de entender.

Entonces, digamos que su alfabeto de elección es

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Entonces, estos dos son equivalentes entre sí, por lo que puede elegir el que sea más intuitivo para usted:

Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

e

Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

Edit:

Me parece como qubyte e Martijón de Milliano Se le ocurrieron soluciones similares a esta última (¡felicitaciones!), que de alguna manera me perdí. Dado que no se ven tan cortos de un vistazo, lo dejaré aquí de todos modos en caso de que alguien realmente quiera una sola línea :-)

Además, reemplazó 'new Array' con 'Array' en todas las soluciones para reducir algunos bytes más.

contestado el 23 de mayo de 17 a las 13:05

¿Por qué no agregar 1? (Math.random()+1).toString(36).substring(7); - mezclar

Porque sumar 1 no resuelve ninguno de los dos problemas discutidos aquí. Por ejemplo, (1) .toString (36) .substring (7) produce una cadena vacía. - amichair

Usar Math.random().toString(36).substring(2,7) da un resultado esperado que es más como el .substring(2, n+2) - jose rex

Array.apply(null, {length: 5}).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('') - Muhammad Umer

Esto es genial, pero cuando se ejecuta en Firefox con N = 16, los últimos ~ 6 dígitos terminan siendo cero ... (Pero satisface el deseo del OP de 5 caracteres aleatorios). eduardo newell

La solución más compacta, porque slice es más corto que substring. Restar del final de la cadena permite evitar el símbolo de punto flotante generado por el random función:

Math.random().toString(36).slice(-5);

o incluso

(+new Date).toString(36).slice(-5);

Actualizar: Se agregó un enfoque más usando btoa método:

btoa(Math.random()).slice(0, 5);
btoa(+new Date).slice(-7, -2);
btoa(+new Date).substr(-7, 5);

// Using Math.random and Base 36:
console.log(Math.random().toString(36).slice(-5));

// Using new Date and Base 36:
console.log((+new Date).toString(36).slice(-5));

// Using Math.random and Base 64 (btoa):
console.log(btoa(Math.random()).slice(0, 5));

// Using new Date and Base 64 (btoa):
console.log(btoa(+new Date).slice(-7, -2));
console.log(btoa(+new Date).substr(-7, 5));

contestado el 26 de mayo de 19 a las 02:05

Math.random().toString(36).slice(-5); - Y si Math.random() devoluciones 0.0? - de rayos X

@ rayos x, obtendrás "0" ;) - valentin podkamennyi

Exactamente. ;) Y si Math.random() devoluciones 0.5 el resultado es "0.i". No estoy seguro si hay otros casos extremos. Solo quería señalar que esta no es una respuesta correcta a la pregunta (5 caracteres de [a-zA-Z0-9]). - de rayos X

@ x-ray, no voy a decir que esta sea la respuesta correcta, solo digo que esta es una versión compacta de la respuesta de @doubletap anterior. Yo personalmente uso (+new Date + Math.random()) para prevenir este caso. De todos modos, gracias por la nota. - valentin podkamennyi

Esto. No sé por qué otras respuestas requieren tanto código. john ktejik

Algo como esto debería funcionar

function randomString(len, charSet) {
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var randomString = '';
    for (var i = 0; i < len; i++) {
        var randomPoz = Math.floor(Math.random() * charSet.length);
        randomString += charSet.substring(randomPoz,randomPoz+1);
    }
    return randomString;
}

Llame con el juego de caracteres predeterminado [a-zA-Z0-9] o envíe el suyo propio:

var randomValue = randomString(5);

var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');

Respondido 28 ago 09, 22:08

Aquí se puede encontrar una variante de ejemplo: mediacollege.com/internet/javascript/number/random.html - David

bien podría simplemente decrementar len directamente en un while círculo - drzaus

Gracias, acabo de publicar a continuación una variación de coffeescript de este ejemplo: stackoverflow.com/a/26682781/262379 - dinis cruz

Si se van a utilizar públicamente, probablemente debería eliminar las vocales. Un poco menos de entropía, pero mucho más seguro, ya que no puede generar palabras que puedan ofender a las personas. Por eso me gusta esto, ya que puedo enviar mi propia cadena de caracteres. Buen trabajo. - Nate Bunney

Una versión más nueva con es6 operador de propagación:

[...Array(30)].map(() => Math.random().toString(36)[2]).join('')

  • LA 30 es un número arbitrario, puede elegir cualquier longitud de token que desee
  • LA 36 es el número de base máximo al que puede pasar numeric.toString (), lo que significa todos los números y letras minúsculas az
  • LA 2 se usa para elegir el tercer índice de la cadena aleatoria que se ve así: "0.mfbiohx64i", podríamos tomar cualquier índice después 0.

respondido 21 nov., 20:16

¿Podrías explicar? Especialmente, ¿por qué pasa 36 a toString () y por qué elige el tercer elemento? - vuza

agradable, pero esta solución no incluye los caracteres [AZ] como se solicitó en la pregunta, solo [a-z0-9] - Nahuel Greco

@NahuelGreco puedes hacer [... Array (30)]. Map (() => Math.random (). ToString (36) [2]). Join (''). ToUpperCase () - tam.teixeira

@ tam.teixeira Creo que no, la pregunta original se hizo para mayúsculas mixtas, cada carácter debe elegirse al azar del conjunto [a-zA-Z0-9]. Esta respuesta no satisface eso. - Nahuel Greco

function randomstring(L) {
  var s = '';
  var randomchar = function() {
    var n = Math.floor(Math.random() * 62);
    if (n < 10) return n; //1-10
    if (n < 36) return String.fromCharCode(n + 55); //A-Z
    return String.fromCharCode(n + 61); //a-z
  }
  while (s.length < L) s += randomchar();
  return s;
}
console.log(randomstring(5));

Respondido el 29 de junio de 17 a las 11:06

Me gusta esto más. Puede modificar fácilmente para aceptar parámetros adicionales y devolver solo nums, lowers o caps. No creo que el estilo ultracomprimido sea necesario while(s.length< L) s+= randomchar(); - mastablasta

También while(L--) lo haré - vsync

Mejor usar el más robusto 'A'.charCodeAt(0) en lugar del número mágico 55 (y lo mismo para el 61). Particularmente porque, en mi plataforma de todos modos, el número mágico que regresa es 65. Ese código también se auto-documentará mejor. - grumdrig

Creé una variante optimizada para la minificación (46 bytes más pequeña) de su implementación aquí: stackoverflow.com/a/52412162 - Waruyama

Generador de cadenas aleatorias (alfanumérico | alfanumérico | numérico)

/**
 * Pseudo-random string generator
 * http://stackoverflow.com/a/27872144/383904
 * Default: return a random alpha-numeric string
 * 
 * @param {Integer} len Desired length
 * @param {String} an Optional (alphanumeric), "a" (alpha), "n" (numeric)
 * @return {String}
 */
function randomString(len, an) {
  an = an && an.toLowerCase();
  var str = "",
    i = 0,
    min = an == "a" ? 10 : 0,
    max = an == "n" ? 10 : 62;
  for (; i++ < len;) {
    var r = Math.random() * (max - min) + min << 0;
    str += String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48);
  }
  return str;
}

console.log(randomString(10));      // i.e: "4Z8iNQag9v"
console.log(randomString(10, "a")); // i.e: "aUkZuHNcWw"
console.log(randomString(10, "n")); // i.e: "9055739230"


Si bien lo anterior utiliza verificaciones adicionales para el A / N, A, N salida, vamos a dividirlo en lo esencial (solo alfanumérico) para una mejor comprensión:

  • Cree una función que acepte un argumento (longitud deseada del resultado de cadena aleatorio)
  • Crea una cadena vacía como var str = ""; para concatenar caracteres aleatorios
  • Dentro de un bucle crear un rand número de índice del 0 - 61 (0..9 + A..Z + a..z = 62)
  • Créar un Lógica condicional a Ajustar / arreglar rand (ya que es 0..61) incrementándolo en algún número (vea los ejemplos a continuación) para volver a la derecha CharCode número y el carácter relacionado.
  • Dentro del bucle concatenar a str a String.fromCharCode( incremented rand )

Imaginemos el Tabla de caracteres ASCII rangos:

_____0....9______A..........Z______a..........z___________  Character
     | 10 |      |    26    |      |    26    |             Tot = 62 characters
    48....57    65..........90    97..........122           CharCode ranges

Math.floor( Math.random * 62 ) da un rango de 0..61 (Lo que necesitamos).
Arreglemos el azar para obtener el correcto rangos de charCode:

      |   rand   | charCode |  (0..61)rand += fix            = charCode ranges |
------+----------+----------+--------------------------------+-----------------+
0..9  |   0..9   |  48..57  |  rand += 48                    =     48..57      |
A..Z  |  10..35  |  65..90  |  rand += 55 /*  90-35 = 55 */  =     65..90      |
a..z  |  36..61  |  97..122 |  rand += 61 /* 122-61 = 61 */  =     97..122     |

LA operación condicional lógica de la tabla de arriba:

   rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand +=  true  ? (  true   ? 55 else 61 ) else 48 ;

De la explicación anterior, aquí está el resultado fragmento alfanumérico:

function randomString(len) {
  var str = "";                                // String result
  for (var i = 0; i < len; i++) {              // Loop `len` times
    var rand = Math.floor(Math.random() * 62); // random: 0..61
    var charCode = rand += rand > 9 ? (rand < 36 ? 55 : 61) : 48; // Get correct charCode
    str += String.fromCharCode(charCode);      // add Character to str
  }
  return str; // After all loops are done, return the concatenated string
}

console.log(randomString(10)); // i.e: "7GL9F0ne6t"

O si quieres:

const randomString = (n, r='') => {
  while (n--) r += String.fromCharCode((r=Math.random()*62|0, r+=r>9?(r<36?55:61):48));
  return r;
};

console.log(randomString(10))

Respondido 13 Feb 20, 10:02

Respuesta perfecta. Muchas gracias. - Rohit Kumar

Por una razón que no pude identificar, x.toString(36) --- como se usa en las respuestas anteriores --- no generaba de manera confiable los mismos caracteres cuando comparé las salidas de dos aplicaciones que tenían diferentes versiones de ES, y esta función solucionó esto para mí, ya que no usa .toString()! - harley lang

La forma más sencilla es:

(new Date%9e6).toString(36)

Esto genera cadenas aleatorias de 5 caracteres según la hora actual. La salida de ejemplo es 4mtxj or 4mv90 or 4mwp1

El problema con esto es que si lo llama dos veces en el mismo segundo, generará la misma cadena.

La forma más segura es:

(0|Math.random()*9e6).toString(36)

Esto generará una cadena aleatoria de 4 o 5 caracteres, siempre diferente. La salida de ejemplo es como 30jzm or 1r591 or 4su1a

De ambas formas, la primera parte genera un número aleatorio. La .toString(36) parte convierte el número en una representación base36 (alfadecimal) del mismo.

respondido 11 mar '15, 22:03

No estoy muy seguro de cómo esto responde a la pregunta; Esta es una pregunta de 7 años con muchas respuestas válidas ya. Si opta por proporcionar una nueva respuesta, debe tener especial cuidado para asegurarse de que su respuesta esté bien explicada y documentada. - Arcillas

Si usa Date, ¿por qué no lo usa como: (+new Date).toString(36) - predicador senior

Me gusta su solución de números aleatorios, pero 9e6 ofrece solo 9 millones de posibilidades sobre los 60.4 millones de 5 dígitos (36 ^ 5), por lo que podría reemplazarlo con (0|Math.random()*6.04e7).toString(36) para cubrirlo. - El droide

Quería una cadena aleatoria larga con una rutina lo más corta posible (para una demostración de código) que no necesita ser criptográficamente sorprendente, solo producir una buena "pelusa" visual aleatoria. Me gusta más esta respuesta (la segunda), así que gracias. Mis dos centavos: puedo superarlo por brevedad con una pulsación menos de tecla, y normalmente producirá 2 caracteres aleatorios (sin un punto): (Math.random()*1e20).toString(36). - andres willems

un reparo que tengo con esta respuesta es que no usará [AZ] que está en la pregunta original. - fácil de usar

Para cumplir con el requisito [a-zA-Z0-9] y la longitud = 5, utilice

btoa(Math.random()).substr(10, 5);

Se producirán letras minúsculas, mayúsculas y números.

respondido 15 nov., 20:02

Supongo que Math.random () podría conducir a una cadena base64 con muy pocos caracteres. - Leif

Al agregar el comentario de @Leif, esto solo generará números entre 1-5 y solo 19 de 52 letras! (mayúsculas y minúsculas) Para probar, ejecútelo varias veces, Set para ver caracteres únicos y luego ordenarlos. un trazador de líneas para eso: [...new Set([...Array(100000)].map(()=>btoa(Math.random()).substr(5, 5)).join(""))].sort() - O Duan

Sé que todos ya lo han hecho bien, pero tenía ganas de intentarlo de la manera más liviana posible (ligero en el código, no en la CPU):

function rand(length, current) {
  current = current ? current : '';
  return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current;
}

console.log(rand(5));

Se necesita un poco de tiempo para entenderlo, pero creo que realmente muestra lo increíble que es la sintaxis de JavaScript.

Respondido el 29 de junio de 17 a las 12:06

Si está tratando de mantener el código corto, ¿por qué escribir current = current ? current : ''; cuando puedes escribir current = current || ''; - caffgeek

ya que estamos hablando de microoptimización aquí, en realidad sugeriría omitir la asignación de variables por completo si no es necesario: current || (current = ''); - Tomas Heymann

Intentar la microoptimización mientras se usa un algoritmo recursivo "agradable" pero que desperdicia recursos no tiene sentido :-) Un bucle for sigue siendo mejor en Javascript y supera la recursividad a lo grande, hasta que se realicen grandes avances en el código de optimización de los tiempos de ejecución. - Más

Aquí hay algunas frases sencillas. Cambio new Array(5) para establecer la longitud.

Incluye 0-9a-z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})

Incluye 0-9a-zA-Z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});

Respondido 26 Oct 15, 14:10

En caso de que alguien esté interesado en un one-liner (aunque no esté formateado como tal para su conveniencia) que asigne la memoria de una vez (pero tenga en cuenta que para cadenas pequeñas realmente no importa) aquí es cómo hacerlo:

Array.apply(0, Array(5)).map(function() {
    return (function(charset){
        return charset.charAt(Math.floor(Math.random() * charset.length))
    }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
}).join('')

Puedes reemplazar 5 por la longitud de la cuerda que desee. Gracias a @AriyaHidayat en esta publicación por la solución al map la función no funciona en la matriz dispersa creada por Array(5).

contestado el 23 de mayo de 17 a las 13:05

Cada programa javascript es un 'one-liner' si lo formatea como tal - hacklikecrack

Si está utilizando Lodash or Subrayar, entonces es tan simple:

var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');

Respondido 20 Abr '16, 06:04

Usos de Lodash _.sampleSize('asdfgh',5).join('') - marlo

En realidad, esta no es una buena solución, porque por docs cada carácter es de un índice único. Eso significa que no es verdaderamente aleatorio, ya que ningún personaje puede repetirse. - nombre_usuario_aleatorio

Este es el método que creé.
Creará una cadena que contiene caracteres tanto en mayúsculas como en minúsculas.
Además, he incluido la función que también creará una cadena alfanumérica.

Ejemplos de trabajo:
http://jsfiddle.net/greatbigmassive/vhsxs/ (solo alfa)
http://jsfiddle.net/greatbigmassive/PJwg8/ (alfanumérico)

function randString(x){
    var s = "";
    while(s.length<x&&x>0){
        var r = Math.random();
        s+= String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65));
    }
    return s;
}

Actualización de julio de 2015
Esto hace lo mismo pero tiene más sentido e incluye todas las letras.

var s = "";
while(s.length<x&&x>0){
    v = Math.random()<0.5?32:0;
    s += String.fromCharCode(Math.round(Math.random()*((122-v)-(97-v))+(97-v)));
}

Respondido 27 Jul 15, 12:07

Con esta función, nunca puede obtener una letra mayúscula mayor que 'M' o una letra minúscula menor que 'n'. - erkanyildiz

¿En serio? ¡Oh! probablemente lo probaré más entonces. Hmm, sin embargo, dado que es una cadena aleatoria y realmente no nos importa qué letras hay en ella (siempre que sean aleatorias), todavía hace lo que queremos que haga, que es todo lo que importa, pero sí, proporcionará un actualizar, gracias. - Adam

const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')

respondido 03 mar '20, 13:03

Solución simple y limpia - marca swardstrom

Esto merece un +1 más grande - walid ammar

¡Guau! Estoy codificando js durante más de 10 años y no sabía nada ~~ ¡truco! ¡Lindo! - Adán Pietrasiak

Asumiendo que usas subrayadojs es posible generar elegantemente cadenas aleatorias en solo dos líneas:

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var random = _.sample(possible, 5).join('');

contestado el 18 de mayo de 15 a las 12:05

Esto hará que el valor devuelto tenga todos los caracteres únicos. Además, la longitud de la cadena está limitada hasta la longitud de var posible. - yefú

Un trazador de líneas:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil

respondido 20 mar '20, 22:03

Para hacerlo más corto, cambie el argumento en Array(15) a un valor menor. P.ej: Array(4). - Arkadyt

Realmente amo esta solución, simple y clara. Genera 15 números aleatorios entre 0 y 1, genera el hexadecimal y luego elimina los dos primeros caracteres. Finalmente los está fusionando todos juntos. - siscia

Genere un alfanumérico aleatorio seguro Base-62 cuerda:

function generateUID(length)
{
    return window.btoa(Array.from(window.crypto.getRandomValues(new Uint8Array(length * 2))).map((b) => String.fromCharCode(b)).join("")).replace(/[+/]/g, "").substring(0, length);
}

console.log(generateUID(22)); // "yFg3Upv2cE9cKOXd7hHwWp"
console.log(generateUID(5)); // "YQGzP"

respondido 08 nov., 20:20

Algoritmo rápido y mejorado. No garantiza uniforme (ver comentarios).

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    let result = '';

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}

Respondido 06 Abr '20, 20:04

Gran respuesta, pero la probabilidad no es uniforme. Hay 62 personajes posibles y crypto.getRandomValues devuelve uno de 256 valores únicos. Debido a que 256 no se divide por 62, terminas teniendo una probabilidad ligeramente mayor de obtener caracteres AH. Creo que la mejor solución es hacer lo que hizo YouTube y agregar 2 caracteres adicionales (posiblemente - e _) al juego de caracteres. De todos modos, gran trabajo, esta respuesta necesita mucho más amor :) - tewu

agregar - y _ es una gran idea, ya que le proporcionará el conjunto completo de base64 seguro para URL - vaquero

Mejorada la respuesta de @ Andrew arriba:

Array.from({ length : 1 }, () => Math.random().toString(36)[2]).join('');

La conversión de base 36 del número aleatorio es inconsistente, por lo que la selección de un solo índice corrige eso. Puede cambiar la longitud de una cuerda con la longitud exacta deseada.

Respondido 24 Jul 20, 22:07

Bonito trazador de líneas, ¡gracias! - biomicrófono

¿Qué tal este pequeño truco compacto?

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var stringLength = 5;

function pickRandom() {
    return possible[Math.floor(Math.random() * possible.length)];
}

var randomString = Array.apply(null, Array(stringLength)).map(pickRandom).join('');

Necesitas el Array.apply allí para engañar a la matriz vacía para que sea una matriz de indefinidos.

Si está codificando para ES2015, entonces construir la matriz es un poco más simple:

var randomString = Array.from({ length: stringLength }, pickRandom).join('');

contestado el 03 de mayo de 17 a las 10:05

Puede recorrer una matriz de elementos y agregarlos de forma recursiva a una variable de cadena, por ejemplo, si desea una secuencia de ADN aleatoria:

function randomDNA(len) {
  len = len || 100
  var nuc = new Array("A", "T", "C", "G")
  var i = 0
  var n = 0
  s = ''
  while (i <= len - 1) {
    n = Math.floor(Math.random() * 4)
    s += nuc[n]
    i++
  }
  return s
}

console.log(randomDNA(5));

Respondido el 29 de junio de 17 a las 11:06

El problema con las respuestas a "Necesito cadenas al azar" preguntas (en cualquier idioma) es prácticamente cada solución utiliza una especificación primaria defectuosa de longitud de la cuerda. Las preguntas en sí mismas rara vez revelan por qué se necesitan las cadenas aleatorias, pero yo le desafiaría a que rara vez necesite cadenas aleatorias de longitud, digamos 8. Lo que invariablemente necesita es un número cuerdas únicas, por ejemplo, para usar como identificadores para algún propósito.

Hay dos formas principales de conseguir estrictamente único cadenas: determinista (que no es aleatorio) y almacenar / comparar (que es oneroso). qué hacemos? Renunciamos al fantasma. Vamos con unicidad probabilística en lugar de. Es decir, aceptamos que existe algún riesgo (por pequeño que sea) de que nuestras cadenas no sean únicas. Aquí es donde la comprensión probabilidad de colisión e entropía son útiles

Así que reformularé la necesidad invariable como la necesidad de una cierta cantidad de cadenas con un pequeño riesgo de repetición. Como ejemplo concreto, digamos que desea generar un potencial de 5 millones de ID. No desea almacenar y comparar cada nueva cadena, y desea que sean aleatorias, por lo que acepta cierto riesgo de repetición. Como ejemplo, digamos un riesgo de menos de 1 en un billón de posibilidades de repetición. Entonces, ¿qué longitud de cuerda necesitas? Bueno, esa pregunta está subespecificada ya que depende de los caracteres utilizados. Pero lo que es más importante, está equivocado. Lo que necesita es una especificación de la entropía de las cadenas, no su longitud. La entropía se puede relacionar directamente con la probabilidad de una repetición en cierto número de cadenas. La longitud de la cuerda no puede.

Y aquí es donde una biblioteca como EntropíaString poder ayudar. Para generar ID aleatorios que tienen menos de 1 en un billón de posibilidades de repetirse en 5 millones de cadenas usando entropy-string:

import {Random, Entropy} from 'entropy-string'

const random = new Random()
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"44hTNghjNHGGRHqH9"

entropy-string utiliza un juego de caracteres con 32 caracteres por defecto. Hay otros conjuntos de caracteres predefinidos y también puede especificar sus propios caracteres. Por ejemplo, generando ID con la misma entropía que arriba pero usando caracteres hexadecimales:

import {Random, Entropy, charSet16} from './entropy-string'

const random = new Random(charSet16)
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"27b33372ade513715481f"

Tenga en cuenta la diferencia en la longitud de la cadena debido a la diferencia en el número total de caracteres en el juego de caracteres utilizado. El riesgo de repetición en el número especificado de cadenas potenciales es el mismo. Las longitudes de las cuerdas no lo son. Y lo mejor de todo es que el riesgo de repetición y el número potencial de cadenas es explícito. No más adivinanzas con la longitud de la cuerda.

Respondido el 02 de Septiembre de 17 a las 22:09

¡Gracias! Su comentario me hizo darme cuenta de que no debería generar ID al azar. Parece que nanoid es mucho más popular que entropy-string y parece tan bueno para mis propósitos. - Altay_H

function randomString (strLength, charSet) {
    var result = [];

    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    while (--strLength) {
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }

    return result.join('');
}

Esto es lo más limpio posible. También es rápido http://jsperf.com/ay-random-string.

Respondido el 10 de enero de 13 a las 02:01

Para mí, esto siempre genera cadenas aleatorias con strLength - 1 : - / - alexgrafe

Cambiando de --strLength a strLength--me lo arregla. - alexgrafe

Caracteres alfanuméricos que no distinguen entre mayúsculas y minúsculas:

function randStr(len) {
  let s = '';
  while (s.length < len) s += Math.random().toString(36).substr(2, len - s.length);
  return s;
}

// usage
console.log(randStr(50));

El beneficio de esta función es que puede obtener una cadena aleatoria de diferente longitud y asegura la longitud de la cadena.

Todos los caracteres sensibles a mayúsculas y minúsculas:

function randStr(len) {
  let s = '';
  while (len--) s += String.fromCodePoint(Math.floor(Math.random() * (126 - 33) + 33));
  return s;
}

// usage
console.log(randStr(50));

Caracteres personalizados

function randStr(len, chars='abc123') {
  let s = '';
  while (len--) s += chars[Math.floor(Math.random() * chars.length)];
  return s;
}

// usage
console.log(randStr(50));
console.log(randStr(50, 'abc'));
console.log(randStr(50, 'aab')); // more a than b

Respondido 15 Oct 18, 14:10

Esta respuesta se ajusta más a mi caso de uso. Sería genial si pudieras agregar un var possible como en la respuesta aceptada, por lo que el resultado de la función es más configurable. - Denis Sabolotni

Esto funciona seguro

<script language="javascript" type="text/javascript">
function randomString() {
 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var string_length = 8;
 var randomstring = '';
 for (var i=0; i<string_length; i++) {
  var rnum = Math.floor(Math.random() * chars.length);
  randomstring += chars.substring(rnum,rnum+1);
 }
 document.randform.randomfield.value = randomstring;
}
</script>

Respondido el 03 de diciembre de 09 a las 08:12

No encontré una solución limpia para admitir caracteres tanto en minúsculas como en mayúsculas.

Soporte solo en minúsculas:

Math.random().toString(36).substr(2, 5)

Sobre la base de esa solución para admitir minúsculas y mayúsculas:

Math.random().toString(36).substr(2, 5).split('').map(c => Math.random() < 0.5 ? c.toUpperCase() : c).join('');

Cambie el 5 in substr(2, 5) para ajustar a la longitud que necesita.

Respondido 05 Feb 18, 21:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.