Pregunta Generar cadena / 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?


1151
2017-08-28 21:14


origen


Respuestas:


Creo que esto funcionará para ti:

function makeid() {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < 5; i++)
    text += possible.charAt(Math.floor(Math.random() * possible.length));

  return text;
}

console.log(makeid());


1637
2017-08-28 21:21



Math.random().toString(36).substring(7);

1726
2017-11-10 18:12



Math.random es malo para este tipo de cosas

Opción 1

Si eres capaz de hacer esto servidorlado, solo usa el crypto módulo

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 genere; cada byte codificado en hex es de 2 caracteres. 20 bytes serán 40 caracteres de hex.


opcion 2

Si tienes que hacer esto cliente-side, tal vez intente con 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
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2)
}

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


238
2018-01-02 19:18



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

Primero, como otros han mencionado, 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. Aquí hay 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 cadena de N a 16 caracteres. Lo siguiente devolverá una cadena de tamaño N para cualquier N (pero tenga en cuenta que usar N> 16 no aumentará la aleatoriedad o disminuirá la probabilidad de colisión):

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 a-z.
  3. Pad con ceros (resuelve el primer problema).
  4. Cortar el líder '0.' prefijo y ceros adicionales de relleno.
  5. Repite la cadena lo suficiente para tener al menos N caracteres en ella (uniendo Cadenas vacías con la cadena aleatoria más corta usada 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 es sobre el soporte de cualquier longitud de cadena solicitada, no sobre la adición de 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 () se distribuyan uniformemente (en cualquier caso, esto no es una aleatoriedad criptográfica).
  • No todas las cadenas posibles de tamaño N pueden ser devueltas. 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. De nuevo, en casi todos los casos no importa, pero cortamos la cadena final desde el principio en lugar de al final de la cadena aleatoria, de modo que las cadenas cortas (por ejemplo, N = 1) no se vean afectadas.

Actualizar:

Aquí hay un par de otras frases de estilo funcional con las que se me ocurrió. Difieren de la solución anterior en que:

  • Utilizan un alfabeto arbitrario explícito (más genérico y adecuado para la pregunta original que solicita 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, di que tu 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('');

y

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

Editar:

Me parece qubyte y Martijn de Milliano surgieron soluciones similares a esta última (¡felicitaciones!), que de alguna manera me perdí. Dado que no se ven tan cortos a simple vista, lo dejaré aquí de todos modos en caso de que alguien realmente quiera un trazador de líneas :-)

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


128
2017-11-13 21:18



Corto, fácil y confiable

Devuelve exactamente 5 caracteres aleatorios, a diferencia de algunas de las respuestas mejor valoradas que se encuentran aquí.

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

126
2017-07-27 20:24



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

Llamar con el juego de caracteres predeterminado [a-zA-Z0-9] o enviar el suyo propio:

var randomValue = randomString(5);

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

81
2017-08-28 21:28



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


61
2017-08-29 02:41



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

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

o incluso

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

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

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


48
2017-10-15 11:11



Random String Generator (Alpha-Numeric | Alpha | Numeric)

/**
 * RANDOM STRING GENERATOR
 *
 * Info:      http://stackoverflow.com/a/27872144/383904
 * Use:       randomString(length [,"A"] [,"N"] );
 * Default:   return a random alpha-numeric string
 * Arguments: If you use the optional "A", "N" flags:
 *            "A" (Alpha flag)   return random a-Z string
 *            "N" (Numeric flag) return random 0-9 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;
}
randomString(10);        // "4Z8iNQag9v"
randomString(10, "A");   // "aUkZuHNcWw"
randomString(10, "N");   // "9055739230"

Que te diviertas. jsBin demo


Mientras que lo anterior usa controles adicionales para la salida deseada (A / N, A, N), vamos a desglosarlo por lo esencial (solo alfa-numérico) para una mejor comprensión:

  • Cree una función que acepte un argumento (longitud deseada del resultado de Cadena aleatoria)
  • Crea una cadena vacía como var str = ""; para concatenar caracteres aleatorios
  • Dentro de un bucle crear un rand número de índice de 0 a 61 (0..9 + A..Z + a..z = 62)
  • Crear un lógica condicional a Ajustar / corregir rand (dado que es 0..61) incrementándolo en algún número (ver ejemplos a continuación) para recuperar el derecho CharCode número y el personaje relacionado.
  • Dentro del bucle concatenar a str un String.fromCharCode( incremented rand )

Imaginemos el Tabla de caracteres y ellos 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). Cómo arreglar (incrementar) 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     |

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

Si siguió la explicación anterior, debería poder crear esto fragmento alfanumérico:

jsBin demo

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) ); // "7GL9F0ne6t"

O si lo desea:

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

40
2018-01-10 02:09