Je veux créer une chaîne exacte de 5 caractères aléatoires avec le moins de possibilité de duplication. Quelle serait la meilleure façon de procéder? Merci.
En utilisant, Random::alphanumericString($length)vous pouvez obtenir des chaînes avec 0-9a-zA-Z qui proviennent de données aléatoires sécurisées par cryptographie.
caw
Réponses:
162
$rand = substr(md5(microtime()),rand(0,26),5);
Ce serait ma meilleure supposition - À moins que vous ne recherchiez également des caractères spéciaux:
$seed = str_split('abcdefghijklmnopqrstuvwxyz'.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.'0123456789!@#$%^&*()');// and any other characters
shuffle($seed);// probably optional since array_is randomized; this may be redundant
$rand ='';foreach(array_rand($seed,5)as $k) $rand .= $seed[$k];
Remarque: incrémentiel signifie plus facile à deviner; Si vous l'utilisez comme un sel ou un jeton de vérification, ne le faites pas. Un sel (maintenant) de "WCWyb" signifie que dans 5 secondes c'est "WCWyg")
Le problème avec l'utilisation md5()est cependant que vous obtenez une chaîne composée d'un jeu de 16 caractères (10 chiffres et aà f, c'est- à -dire 4 bits par caractère de chaîne). Cela peut être suffisant à certaines fins, mais peut être insuffisant à des fins cryptographiques (cinq caractères sur 16 symboles = 16 ^ 5 = 20 bits = 1048576 possibilités).
Arc
3
array_rand($seed, 5)renverra une clé de tableau, pas une valeur, donc votre code ne fonctionnera pas
alumi
1
Je pense que l'utilisation d'une fonction de hachage cryptographique pour générer des caractères aléatoires est au moins inappropriée.
gronostaj
Est - il possible aussi d'inclure ", 'et anti - slash $charset? Dois-je utiliser des séquences d'échappement pour inclure ces caractères?
Mai
1
Le deuxième extrait n'utilise même pas le $lenparamètre d'entrée ... l'avez-vous oublié?
TechNyquist
76
Si les forboucles sont rares, voici ce que j'aime utiliser:
Solution intéressante ... très concise, même si je me demande si c'est plus rapide ou plus lent que d'utiliser pour. Ne peut pas être dérangé par le benchmark cependant :-)
Arc
@matthew str_shuffle produira des doublons en continu
SCC
@ user2826057: str_shuffle('ab')donnerait abou bamais jamais aa. L'ajout du str_repeatpermet pour cela. Mais cela dit, la solution que j'ai donnée n'est pas vraiment sérieuse ... même si elle fonctionne.
Matthew
2
Il y a une chance 1/60466176 que cela se produise, en supposant que le RNG est uniformément distribué.
Matthieu
1
Ceci est parfait pour notre cas d'utilisation de génération de codes promotionnels. Nous avons retiré les caractères confus, comme l, i, 1, 0, O, etc et de 500 bons a obtenu pas de doublons.
Luke Cousins
25
Un moyen rapide consiste à utiliser les caractères les plus volatils de la fonction uniqid .
Ce qui suit devrait fournir le moins de chances de duplication (vous voudrez peut-être remplacer mt_rand()par une meilleure source de nombres aléatoires, par exemple à partir /dev/*randomou à partir de GUID):
Premier exemple plus intelligent avec $ result. = $ Characters [mt_rand (0, strlen ($ characters) -1)]
hamboy75
Dans ce cas, vous devez déterminer la longueur au préalable et la stocker au moins dans une variable. L'utilisation strlen()en boucle est inutile, surtout si vous savez déjà que le jeu de caractères ne changera pas entre-temps.
Arc
J'en doute, php est optimisé, de toute façon c'est une option :)
hamboy75
7
J'utilise toujours la même fonction pour cela, généralement pour générer des mots de passe. C'est facile à utiliser et utile.
Je pense que l'utilisation des fonctions de hachage est excessive pour une tâche aussi simple que la génération d'une séquence de chiffres hexadécimaux aléatoires. dechex+ mt_randfera le même travail, mais sans travail cryptographique inutile.str_padgarantit la longueur de 5 caractères de la chaîne de sortie (si le nombre aléatoire est inférieur à 0x10000).
La probabilité de duplication dépend de mt_randla fiabilité de. Mersenne Twister est connu pour son caractère aléatoire de haute qualité, il devrait donc bien s'adapter à la tâche.
Je ne savais pas non plus comment faire cela avant de penser à utiliser PHP array. Et je suis presque sûr que c'est le moyen le plus simple de générer une chaîne ou un nombre aléatoire avec des tableaux. Le code:
Comme l'a souligné Archimedix , cela ne garantira pas de renvoyer une "moindre possibilité de duplication" car le nombre de combinaisons est faible pour la plage de caractères donnée. Vous devrez soit augmenter le nombre de caractères, soit autoriser des caractères supplémentaires (spéciaux) dans la chaîne. La première solution serait préférable, je pense, dans votre cas.
L'utilisation time()est jusqu'à 1 million de fois plus prévisible que microtime().
Arc
Notez également mes commentaires sur la réponse de Brad, le plus gros problème est que le hachage généré est une représentation hexadécimale composée de 16 caractères valides, ne laissant donc que 1024 variations pour $str.
Arc
@Archimedix, peut-être, mais l'OP n'a pas demandé de sécurité, la question a été définie pour avoir un algorithme de génération de chaîne consistant en une combinaison de 5x26 caractères différents et en évitant les doublons. Il s'agit probablement d'un numéro de référence de confirmation dans un processus d'inscription (ou de facturation), ou quelque chose comme ça
Yanick Rochon
Je crois comprendre qu'il a demandé la moindre possibilité de duplication , et cela a une probabilité de 0,1% (1 sur 1024) qui aurait pu être de près de 1 sur 1 milliard.
Arc
cependant, si vous avez besoin de générer une clé de référence de 5 caractères et de lui donner un client / client, vous ne voulez pas leur donner " ˫§»⁋⅓" simplement parce que c'est plus sécurisé ... vous augmentez votre clé de référence à 7 caractères ou plus . (BTW: correction dans mon commentaire précédent, c'est 5x36 caractères)
function cvf_ps_generate_random_code($length=10){
$string ='';// You can define your own characters here.
$characters ="23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";for($p =0; $p < $length; $p++){
$string .= $characters[mt_rand(0, strlen($characters)-1)];}return $string;}
La nouvelle fonction de PHP password_hash()(*> = PHP 5.5) fait le travail pour la génération d'un ensemble décemment long de caractères et de nombres majuscules et minuscules.
Deux concat. les chaînes avant et après password_hashdans la fonction $ random peuvent être modifiées.
Les paramètres pour $random()* ($ a, $ b) sont en fait des substr()paramètres. :)
REMARQUE: cela n'a pas besoin d'être une fonction, cela peut aussi être une variable normale ... comme un méchant singleliner, comme ceci:
Conseil de pro - Incluez des explications sur la façon dont votre réponse résout le problème du PO et pourquoi elle pourrait être différente des autres réponses déjà fournies.
0-9a-zA-Z
?Random::alphanumericString($length)
vous pouvez obtenir des chaînes avec 0-9a-zA-Z qui proviennent de données aléatoires sécurisées par cryptographie.Réponses:
Ce serait ma meilleure supposition - À moins que vous ne recherchiez également des caractères spéciaux:
Exemple
Et, pour celui basé sur l'horloge (moins de collisions puisque c'est incrémental):
Remarque: incrémentiel signifie plus facile à deviner; Si vous l'utilisez comme un sel ou un jeton de vérification, ne le faites pas. Un sel (maintenant) de "WCWyb" signifie que dans 5 secondes c'est "WCWyg")
la source
md5()
est cependant que vous obtenez une chaîne composée d'un jeu de 16 caractères (10 chiffres eta
àf
, c'est- à -dire 4 bits par caractère de chaîne). Cela peut être suffisant à certaines fins, mais peut être insuffisant à des fins cryptographiques (cinq caractères sur 16 symboles = 16 ^ 5 = 20 bits = 1048576 possibilités).array_rand($seed, 5)
renverra une clé de tableau, pas une valeur, donc votre code ne fonctionnera pas"
,'
et anti - slash$charset
? Dois-je utiliser des séquences d'échappement pour inclure ces caractères?$len
paramètre d'entrée ... l'avez-vous oublié?Si les
for
boucles sont rares, voici ce que j'aime utiliser:la source
str_shuffle('ab')
donneraitab
ouba
mais jamaisaa
. L'ajout dustr_repeat
permet pour cela. Mais cela dit, la solution que j'ai donnée n'est pas vraiment sérieuse ... même si elle fonctionne.l
,i
,1
,0
,O
, etc et de 500 bons a obtenu pas de doublons.Un moyen rapide consiste à utiliser les caractères les plus volatils de la fonction uniqid .
Par exemple:
la source
Vous pouvez l'essayer simplement comme ceci:
plus de détails: http://forum.arnlweb.com/viewtopic.php?f=7&t=25
la source
Ce qui suit devrait fournir le moins de chances de duplication (vous voudrez peut-être remplacer
mt_rand()
par une meilleure source de nombres aléatoires, par exemple à partir/dev/*random
ou à partir de GUID):EDIT:
Si vous êtes préoccupé par la sécurité, vraiment, ne pas utiliser
rand()
oumt_rand()
, et vérifiez que votre appareil de données aléatoires est en fait un dispositif de génération aléatoire de données, pas un fichier régulier ou quelque chose comme prévisible/dev/zero
.mt_rand()
considéré comme dangereux:https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php
EDIT: Si vous avez le support OpenSSL en PHP, vous pouvez utiliser
openssl_random_pseudo_bytes()
:la source
strlen()
en boucle est inutile, surtout si vous savez déjà que le jeu de caractères ne changera pas entre-temps.J'utilise toujours la même fonction pour cela, généralement pour générer des mots de passe. C'est facile à utiliser et utile.
la source
Il semble que str_shuffle serait une bonne utilisation pour cela. Amorcez le mélange avec les caractères de votre choix.
la source
la source
Si c'est bien que vous n'obteniez que des lettres AF, alors voici ma solution:
Je pense que l'utilisation des fonctions de hachage est excessive pour une tâche aussi simple que la génération d'une séquence de chiffres hexadécimaux aléatoires.
dechex
+mt_rand
fera le même travail, mais sans travail cryptographique inutile.str_pad
garantit la longueur de 5 caractères de la chaîne de sortie (si le nombre aléatoire est inférieur à 0x10000).La probabilité de duplication dépend de
mt_rand
la fiabilité de. Mersenne Twister est connu pour son caractère aléatoire de haute qualité, il devrait donc bien s'adapter à la tâche.la source
Je ne savais pas non plus comment faire cela avant de penser à utiliser PHP
array
. Et je suis presque sûr que c'est le moyen le plus simple de générer une chaîne ou un nombre aléatoire avec des tableaux. Le code:Vous pouvez utiliser cette fonction comme ceci
la source
Similaire à la réponse de Brad Christie , mais utilisant l'
sha1
alrorithme pour les caractères0-9a-zA-Z
et précédé d'une valeur aléatoire:Mais si vous avez défini des caractères définis (autorisés):
** MISE À JOUR **
Comme l'a souligné Archimedix , cela ne garantira pas de renvoyer une "moindre possibilité de duplication" car le nombre de combinaisons est faible pour la plage de caractères donnée. Vous devrez soit augmenter le nombre de caractères, soit autoriser des caractères supplémentaires (spéciaux) dans la chaîne. La première solution serait préférable, je pense, dans votre cas.
la source
time()
est jusqu'à 1 million de fois plus prévisible quemicrotime()
.$str
.˫§»⁋⅓
" simplement parce que c'est plus sécurisé ... vous augmentez votre clé de référence à 7 caractères ou plus . (BTW: correction dans mon commentaire précédent, c'est 5x36 caractères)fonctionne bien en PHP (php 5.4.4)
Démo en direct
la source
Source: Fonction PHP qui génère des caractères aléatoires
Cette fonction PHP simple a fonctionné pour moi:
Usage:
la source
Voici mes
random 5 cents
...La nouvelle fonction de PHP
password_hash()
(*> = PHP 5.5) fait le travail pour la génération d'un ensemble décemment long de caractères et de nombres majuscules et minuscules.Deux concat. les chaînes avant et après
password_hash
dans la fonction $ random peuvent être modifiées.Les paramètres pour
$random()
* ($ a, $ b) sont en fait dessubstr()
paramètres. :)REMARQUE: cela n'a pas besoin d'être une fonction, cela peut aussi être une variable normale ... comme un méchant singleliner, comme ceci:
la source
la source
J'utilise toujours ceci:
Lorsque vous l'appelez, définit la longueur de la chaîne.
Vous pouvez également modifier les caractères possibles dans la chaîne
$a
.la source