Question Générer des chaînes / caractères aléatoires en JavaScript


Je veux une chaîne de 5 caractères composée de caractères choisis au hasard de l'ensemble [a-zA-Z0-9].

Quelle est la meilleure façon de le faire avec JavaScript?


1151
2017-08-28 21:14


origine


Réponses:


Je pense que cela fonctionnera pour vous:

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 est mauvais pour ce genre de chose

Option 1

Si vous êtes capable de le faire serveur-side, utilisez simplement le crypto module

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

// "bb5dc8842ca31d4603d6aa11448d1654"

La chaîne résultante sera deux fois plus longue que les octets aléatoires que vous générez; chaque octet codé en hexadécimal est de 2 caractères. 20 octets seront 40 caractères d'hex.


Option 2

Si vous devez le faire client-side, peut-être essayer le module uuid

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

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

Option 3

Si vous devez le faire client-side et vous n'avez pas à supporter les anciens navigateurs, vous pouvez le faire sans dépendances

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



Voici une amélioration sur l'excellente réponse de doubletap. L'original a deux inconvénients qui sont abordés ici:

Tout d'abord, comme d'autres l'ont mentionné, il a une petite probabilité de produire des chaînes courtes ou même une chaîne vide (si le nombre aléatoire est 0), ce qui peut casser votre application. Voici une solution:

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

Deuxièmement, l'original et la solution ci-dessus limitent la taille de la chaîne N à 16 caractères. Ce qui suit retournera une chaîne de taille N pour tout N (mais notez que l'utilisation de N> 16 n'augmentera pas le caractère aléatoire ou diminuera la probabilité de collisions):

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

Explication:

  1. Choisissez un nombre aléatoire dans la plage [0,1), c'est-à-dire entre 0 (inclusif) et 1 (exclusif).
  2. Convertissez le nombre en une chaîne de base 36, c'est-à-dire en utilisant les caractères 0-9 et a-z.
  3. Pad avec zéros (résout le premier problème).
  4. Couper le premier «0». préfixe et zéros de remplissage supplémentaires.
  5. Répétez la chaîne assez souvent pour avoir au moins N caractères (en joignant les chaînes vides avec la chaîne aléatoire plus courte utilisée comme délimiteur).
  6. Trancher exactement N caractères de la chaîne.

D'autres pensées:

  • Cette solution n'utilise pas de majuscules, mais dans presque tous les cas (sans jeu de mots) cela n'a pas d'importance.
  • La longueur de chaîne maximale à N = 16 dans la réponse d'origine est mesurée dans Chrome. Dans Firefox, c'est N = 11. Mais comme expliqué, la deuxième solution consiste à prendre en charge toute longueur de chaîne demandée, et non à ajouter un caractère aléatoire, de sorte que cela ne fait pas beaucoup de différence.
  • Toutes les chaînes renvoyées ont une probabilité égale d'être renvoyées, au moins dans la mesure où les résultats renvoyés par Math.random () sont distribués uniformément (ce n'est pas du tout un caractère aléatoire de force cryptographique).
  • Toutes les chaînes possibles de taille N ne peuvent pas être retournées. Dans la deuxième solution, cela est évident (puisque la plus petite chaîne est simplement dupliquée), mais aussi dans la réponse originale, car dans la conversion en base-36, les derniers bits peuvent ne pas faire partie des bits aléatoires originaux. Plus précisément, si vous regardez le résultat de Math.random (). ToString (36), vous remarquerez que le dernier caractère n'est pas distribué de manière égale. Encore une fois, dans la plupart des cas, cela n'a pas d'importance, mais nous tranchons la chaîne finale au début plutôt qu'à la fin de la chaîne aléatoire afin que les chaînes courtes (par exemple N = 1) ne soient pas affectées.

Mettre à jour:

Voici quelques autres one-liners fonctionnels que j'ai inventés. Ils diffèrent de la solution ci-dessus en ce que:

  • Ils utilisent un alphabet arbitraire explicite (plus générique, et adapté à la question initiale qui demandait à la fois des majuscules et des minuscules).
  • Toutes les chaînes de longueur N ont une probabilité égale d'être renvoyées (c'est-à-dire que les chaînes ne contiennent pas de répétitions).
  • Ils sont basés sur une fonction de carte, plutôt que sur l'astuce toString (36), ce qui les rend plus simples et plus faciles à comprendre.

Donc, dis que ton alphabet de choix est

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Alors ces deux sont équivalents les uns aux autres, ainsi vous pouvez choisir celui qui vous est le plus intuitif:

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

et

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

Modifier:

J'ai l'impression qubyte et Martijn de Milliano est venu avec des solutions similaires à ce dernier (kudos!), que j'ai raté d'une manière ou d'une autre. Comme ils ne semblent pas si courts, je les laisserai de toute façon au cas où quelqu'un voudrait vraiment un one-liner :-)

En outre, remplacé «nouveau tableau» par «tableau» dans toutes les solutions pour raser encore quelques octets.


128
2017-11-13 21:18



Court, facile et fiable

Renvoie exactement 5 caractères aléatoires, par opposition à certaines des réponses les mieux notées trouvées ici.

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

126
2017-07-27 20:24



Quelque chose comme ça devrait fonctionner

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

Appelez le jeu de caractères par défaut [a-zA-Z0-9] ou envoyez le vôtre:

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 solution la plus compacte, car slice est plus courte que substring. Soustraire de la fin de la chaîne permet d'éviter le symbole de virgule flottante généré par random fonction:

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

ou même

(+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



Générateur de chaîne aléatoire (Alpha-Numérique | Alpha | Numérique)

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

S'amuser. jsBin démo


Alors que ce qui précède utilise des contrôles supplémentaires pour la sortie souhaitée (A / N, A, N), décomposons-le à l'essentiel (Alpha-Numeric seulement) pour une meilleure compréhension:

  • Créer une fonction qui accepte un argument (longueur souhaitée du résultat de la chaîne aléatoire)
  • Créer une chaîne vide comme var str = ""; concaténer des caractères aléatoires
  • Dans une boucle créer un rand numéro d'index de 0 à 61 (0..9 + A..Z + a..z = 62)
  • Créer un logique conditionnelle à Ajuster / corriger rand (puisque c'est 0..61) en l'incrémentant d'un certain nombre (voir les exemples ci-dessous) pour revenir à droite CharCode numéro et le caractère associé.
  • Dans la boucle concaténer à str une String.fromCharCode( incremented rand )

Imaginons le Table de caractères et leur gammes:

_____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 ) donne une gamme de 0..61 (ce dont nous avons besoin). Comment réparer (incrémenter) le hasard pour obtenir la bonne Les gammes 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     |

le opération conditionnelle logique du tableau ci-dessus:

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

Si vous avez suivi l'explication ci-dessus, vous devriez être capable de créer cette extrait alphanumérique:

jsBin démo

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"

Ou si vous voulez:

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