web-dev-qa-db-fra.com

Chaîne alphanumérique aléatoire en JavaScript?

Quel est le moyen le plus court (dans les limites du raisonnable) de générer une chaîne aléatoire alphanumérique (majuscules, minuscules et chiffres) en JavaScript à utiliser comme identifiant probablement unique?

184
Pavel

Si vous souhaitez uniquement autoriser des caractères spécifiques, vous pouvez également le faire comme suit:

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

Voici un jsfiddle à démontrer: http://jsfiddle.net/wSQBx/

Une autre méthode consiste à utiliser une chaîne spéciale indiquant à la fonction les types de caractères à utiliser. Vous pouvez faire ça comme ça:

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

Violon: http://jsfiddle.net/wSQBx/2/

Sinon, pour utiliser la méthode base36 comme décrit ci-dessous, procédez comme suit:

function randomString(length) {
    return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
253
Nimphious

Je viens de découvrir cela comme une solution vraiment gentille et élégante:

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

Notes sur cette implémentation:

  • Cela produira une chaîne comprise entre zéro et 12 caractères, généralement 11, car la chaîne de caractères en virgule flottante supprime les zéros de fin.
  • Il ne générera pas de lettres majuscules, mais uniquement des minuscules et des chiffres.
  • Étant donné que le caractère aléatoire provient de Math.random(), la sortie peut être prévisible et donc pas nécessairement unique.
  • Même en supposant une mise en œuvre idéale, la sortie comporte au maximum 52 bits d'entropie, ce qui signifie que vous pouvez vous attendre à une copie après environ 70 millions de chaînes générées.
306
JAR.JAR.beans

Une autre variante de réponse proposée par JAR.JAR.beans

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

En modifiant le multiplicateur 1e32, vous pouvez modifier la longueur d'une chaîne aléatoire.

28
he-yaeh

Ou pour reprendre ce que Jar Jar a suggéré, voici ce que j’ai utilisé dans un projet récent (pour surmonter les restrictions de longueur):

var randomString = function (len, bits)
{
    bits = bits || 36;
    var outStr = "", newStr;
    while (outStr.length < len)
    {
        newStr = Math.random().toString(bits).slice(2);
        outStr += newStr.slice(0, Math.min(newStr.length, (len - outStr.length)));
    }
    return outStr.toUpperCase();
};

Utilisation:

randomString(12, 16); // 12 hexadecimal characters
randomString(200); // 200 alphanumeric characters
19
Josh Mc

C'est plus propre

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

Exemple

Math.random().toString(36).substr(2, 5)
16
Diego Mello

Une ligne avec lodash, pour 20 caractères aléatoires (minuscule alphanumérique):

_.times(20, () => _.random(35).toString(36)).join('');
16
DS.

pour 32 caractères:

for(var c = ''; c.length < 32;) c += Math.random().toString(36).substr(2, 1)
8
Collin Anderson

Je pense que ce qui suit est la solution la plus simple qui permet une longueur donnée:

Array(myLength).fill(0).map(x => Math.random().toString(36).charAt(2)).join('')

Cela dépend de la syntaxe de la fonction de flèche.

7
László Monda

Caractère aléatoire:

String.fromCharCode(i); //where is an int

Aléatoire int:

Math.floor(Math.random()*100);

Mets le tout ensemble:

function randomNum(hi){
    return Math.floor(Math.random()*hi);
} 
function randomChar(){
    return String.fromCharCode(randomNum(100));
}
function randomString(length){
   var str = "";
   for(var i = 0; i < length; ++i){
        str += randomChar();
   }
   return str;
}
var RandomString = randomString(32); //32 length string

Violon: http://jsfiddle.net/maniator/QZ9J2/

6
Neal
_function randomString(len) {
    var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    return [...Array(len)].reduce(a=>a+p[~~(Math.random()*p.length)],'');
}
_

Sommaire:

  1. Créez un tableau de la taille souhaitée (car javascript n'a pas d'équivalent range(len).
  2. Pour chaque élément du tableau: choisissez un caractère aléatoire dans p et ajoutez-le à une chaîne
  3. Renvoie la chaîne générée.

Quelques explications:

[...Array(len)]

Tableau (len) ou nouveau tableau (len) crée un tableau avec un ou plusieurs pointeurs non définis . Les monolithes seront plus difficiles à retirer. La syntaxe Spread définit commodément les pointeurs (à présent, ils pointent vers des objets non définis!).

_.reduce(_

réduire le tableau à, dans ce cas, une seule chaîne. La fonctionnalité de réduction est commune dans la plupart des langues et vaut la peine d'être apprise.

_a=>a+..._

Nous utilisons un fonction flèche .

a est l'accumulateur . Dans ce cas, c'est la chaîne de résultat final que nous allons renvoyer lorsque nous aurons terminé (vous savez c'est une chaîne parce que le deuxième argument de la fonction de réduction, la initialValue est une chaîne vide: _''_). Donc, fondamentalement: convertissez chaque élément du tableau avec p[~~(Math.random()*p.length)], ajoutez le résultat à la chaîne a et donnez-moi a lorsque vous avez terminé.

_p[...]_

p est la chaîne de caractères que nous avons sélectionnée. Vous pouvez accéder aux caractères d'une chaîne comme un index (par exemple, par exemple, _"abcdefg"[3]_ nous donne _"d"_)

~~(Math.random()*p.length)

Math.random() renvoie un nombre à virgule flottante compris entre [0, 1) Math.floor(Math.random()*max)est le standard de facto pour obtenir un entier aléatoire en javascript . ~ est l'opérateur NOT au niveau du bit en javascript. _~~_ est un moyen plus court, sans doute parfois plus rapide, et certainement plus amusant de dire _Math.floor(_ Voici quelques informations

5
roundar

En utilisant lodash:

function createRandomString(length) {
        var chars = "abcdefghijklmnopqrstufwxyzABCDEFGHIJKLMNOPQRSTUFWXYZ1234567890"
        var pwd = _.sampleSize(chars, length || 12)  // lodash v4: use _.sampleSize
        return pwd.join("")
    }
document.write(createRandomString(8))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
2
Dr Hund
var randomString = function(length) {
  var str = '';
  var chars ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(
      '');
  var charsLen = chars.length;
  if (!length) {
    length = ~~(Math.random() * charsLen);
  }
  for (var i = 0; i < length; i++) {
    str += chars[~~(Math.random() * charsLen)];
  }
  return str;
};
2
Joey Dias

Quand j'ai vu cette question, j'ai pensé au moment où je devais générer des UUID. Je ne peux pas prendre crédit pour le code, car je suis sûr de l'avoir trouvé ici sur stackoverflow. Si vous ne voulez pas les tirets dans votre chaîne, supprimez-les. Voici la fonction:

function generateUUID() {
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c) {
        var r = (d + Math.random()*16)%16 | 0;
        d = Math.floor(d/16);
        return (c=='x' ? r : (r&0x7|0x8)).toString(16);
    });
    return uuid.toUpperCase();
}

Fiddle: http://jsfiddle.net/nlviands/fNPvf/11227/

1
nlv

Générateur de clé aléatoire

l'argument keyLength est la longueur de caractère souhaitée pour la clé.

function keyGen(keyLength) {
    var i, key = "", characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    var charactersLength = characters.length;

    for (i = 0; i < keyLength; i++) {
        key += characters.substr(Math.floor((Math.random() * charactersLength) + 1), 1);
    }

    return key;
}


keyGen(12)
"QEt9mYBiTpYD"
1
seaBass

Cette fonction devrait donner une chaîne aléatoire de n'importe quelle longueur.

function randString(length) {
    var l = length > 25 ? 25 : length;
    var str = Math.random().toString(36).substr(2, l);
    if(str.length >= length){
        return str;
    }
    return str.concat(this.randString(length - str.length));
}

Je l'ai testé avec le test suivant qui a réussi.

function test(){
    for(var x = 0; x < 300000; x++){
        if(randString(x).length != x){
            throw new Error('invalid result for len ' + x);
        }
    }
}

La raison pour laquelle j'ai choisi 25 est que, dans la pratique, la longueur de la chaîne renvoyée par Math.random().toString(36).substr(2, 25) a une longueur de 25. Ce nombre peut être modifié à votre guise.

Cette fonction est récursive et il est donc possible d'appeler la fonction avec des valeurs très grandes avec Maximum call stack size exceeded. De mes tests, j'ai pu obtenir une chaîne d'une longueur de 300 000 caractères.

Cette fonction peut être convertie en récursion finale en envoyant la chaîne à la fonction en tant que second paramètre. Je ne sais pas si JS utilise l'optimisation d'appel Tail

1
Yaki Klein

Sympa et simple, et pas limité à un certain nombre de caractères:

let len = 20, str = "";
while(str.length < len) str += Math.random().toString(36).substr(2);
str = str.substr(0, len);
1
user993683