Je veux une chaîne de 5 caractères composée de caractères pris au hasard dans l'ensemble [a-zA-Z0-9]
.
Quelle est la meilleure façon de faire cela avec JavaScript ?
Je veux une chaîne de 5 caractères composée de caractères pris au hasard dans l'ensemble [a-zA-Z0-9]
.
Quelle est la meilleure façon de faire cela avec JavaScript ?
Je pense que ça va marcher pour vous :
function makeid(length) {
var result = [];
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result.push(characters.charAt(Math.floor(Math.random() *
charactersLength)));
}
return result.join('');
}
console.log(makeid(5));
Cela convient pour les chaînes courtes, mais attention, l'utilisation de l'option +=
sur des chaînes de caractères comme celle-ci lui donne un comportement O(n^2). Si vous voulez créer des chaînes de caractères plus longues, vous devriez créer un tableau de caractères individuels et les réunir à la fin.
@dan_waterworth Ça n'a probablement pas d'importance dans presque tout cas : codinghorror.com/blog/2009/01/
Ça peut sembler faux, mais floor
est inutile : for(var text='' ; text.length < 5 ;) text += possible.charAt(Math.random() * possible.length)
let r = Math.random().toString(36).substring(7);
console.log("random", r);
Note : L'algorithme ci-dessus présente les faiblesses suivantes :
Math.random()
peut produire une sortie prévisible ("d'apparence aléatoire" mais pas vraiment aléatoire) selon l'implémentation. La chaîne qui en résulte ne convient pas lorsque vous devez garantir l'unicité ou l'imprévisibilité.
Math.random().toString(36).substr(2, 5)
parce que .substring(7)
fait en sorte qu'il soit plus long que 5 caractères. Des points, quand même !
Et une version compatible avec ActionScript 2 : Math.round(Math.random()*Math.pow(36,5)).toString(36)
Voici une amélioration de L'excellente réponse de doubletap . L'original présente deux inconvénients qui sont abordés ici :
Tout d'abord, comme d'autres l'ont mentionné, il a une faible 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. La solution suivante renverra 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 et ne diminuera pas la probabilité de collisions) :
Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)
Explication :
Autres réflexions :
Mise à jour :
Voici quelques autres répliques de style fonctionnel que j'ai trouvées. Ils diffèrent de la solution ci-dessus en ce que :
Donc, disons que votre alphabet de choix est
var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Les deux sont donc équivalentes, et vous pouvez choisir celle qui vous semble la plus intuitive :
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('');
Edit :
J'ai l'impression que qubyte et Martijn de Milliano a proposé des solutions similaires à la dernière (bravo !), ce qui m'a échappé. Comme elles n'ont pas l'air aussi courtes au premier coup d'œil, je vais quand même les laisser ici au cas où quelqu'un voudrait vraiment une solution en une phrase :-)
J'ai également remplacé "new Array" par "Array" dans toutes les solutions pour gagner quelques octets supplémentaires.
Parce qu'ajouter 1 ne résout aucun des deux problèmes discutés ici. Par exemple, (1).toString(36).substring(7) produit une chaîne vide.
Utilisation de Math.random().toString(36).substring(2,7)
donne un résultat attendu qui ressemble davantage au .substring(2, n+2)
Quelque chose comme ceci 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 avec 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');
Une variante de cet exemple peut être trouvée ici : mediacollege.com/internet/javascript/number/random.html
Merci, je viens de poster ci-dessous une variante coffeescript de cet exemple : stackoverflow.com/a/26682781/262379
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));
C'est celle que je préfère. Vous pourriez facilement le modifier pour qu'il accepte des paramètres supplémentaires et qu'il ne renvoie que des nombres, des minima ou des maxima. Je ne pense pas que le style ultra-compressé soit nécessaire. while(s.length< L) s+= randomchar();
Il est préférable d'utiliser le plus robuste 'A'.charCodeAt(0)
plutôt que le nombre magique 55
(et de même pour le 61
). D'autant plus que, sur ma plateforme en tout cas, le nombre magique qui revient est 65
. Ce code s'auto-documentera mieux aussi.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
87 votes
Avertissement : Aucune des réponses n'a de
true-random
résultat ! Ils ne sont quepseudo-random
. Lorsque vous utilisez des chaînes aléatoires pour la protection ou la sécurité, n'en utilisez aucune ! !! Essayez l'une de ces api : random.org56 votes
Math.random().toString(36).replace(/[^a-z]+/g, '')
20 votes
Veuillez mettre la solution dans une solution.
267 votes
Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
2 votes
@MuazKhan @frieder la gamme de résultats est de
[a-zA-Z0-9]
alors pourquoi le[^a-z]
? Et que dire des lettres majuscules aléatoires ?0 votes
@ring0 c'est assez basique non ? .toUpperCase() à la fin.
22 votes
Note HTML5 webcrypto randomness API fournit un véritable caractère aléatoire.
0 votes
Si vous utilisez
Lodash
ouUnderscore
alors stackoverflow.com/questions/1349404/1 votes
J'ai testé la solution de @frieder sur Node.js v6.9.4 sur Fedora et j'ai observé qu'elle pouvait produire des chaînes plus courtes que 5 caractères. Je n'ai pas étudié comment l'astuce fonctionne, mais pour généraliser la solution on peut plutôt faire
(new Array(5)).fill(0).map(() => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 1)).join("")
qui fonctionne avec des chaînes cibles arbitrairement longues.0 votes
Si vous vous sentez paresseux et que vous n'avez besoin que de nombres pseudo-aléatoires, vous pouvez faire ceci :
Math.floor(Math.random() * Number.MAX_VALUE).toString()
1 votes
Pourquoi avez-vous besoin de cette chaîne ? Une réponse attentive conduira sans doute à une forme de "besoin d'unicité". Dans ce cas, vous avez réellement besoin d'une chaîne représentant une entropie spécifiée, et non d'une chaîne d'une longueur spécifiée utilisant un ensemble de caractères (comme indiqué). A savoir, savez-vous que vous avez demandé une chaîne aléatoire de 29,8 bits d'entropie ? Pourquoi 29,8 bits ? Comprenez-vous clairement ce que ce nombre de bits vous donne en termes de probabilité de répétition dans la génération d'un certain nombre de ces chaînes ? Si cela vous semble flou, consultez entropy-string ( npmjs.com/package/entropy-string ).
6 votes
Si quelqu'un cherche à générer un identifiant ou un identifiant unique, laissez votre base de données faire ce travail ou utilisez plutôt une bibliothèque UUID.