web-dev-qa-db-fra.com

Générer une chaîne aléatoire de 5 caractères

Je veux créer une chaîne exacte de 5 caractères aléatoires avec le moins de possibilités d'obtenir une copie. Quelle serait la meilleure façon de le faire? Merci.

79
Peter
$Rand = substr(md5(microtime()),Rand(0,26),5);

Ce serait ma meilleure supposition - À moins que vous ne recherchiez des caractères spéciaux aussi:

$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];

Exemple

Et, pour l'un basé sur l'horloge (moins de collisions puisque c'est incrémental):

function incrementalHash($len = 5){
  $charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  $base = strlen($charset);
  $result = '';

  $now = explode(' ', microtime())[1];
  while ($now >= $base){
    $i = $now % $base;
    $result = $charset[$i] . $result;
    $now /= $base;
  }
  return substr($result, -5);
}

Note: incrémentiel signifie plus facile à deviner; Si vous utilisez ceci comme un sel ou un jeton de vérification, ne le faites pas. Un sel (maintenant) de "WCWyb" signifie 5 secondes à partir de maintenant c'est "WCWyg")

136
Brad Christie

Si les boucles for sont en nombre insuffisant, voici ce que j'aime utiliser:

$s = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
63
Matthew

Un moyen rapide consiste à utiliser les caractères les plus volatils de la fonction uniqid .

Par exemple:

$Rand = substr(uniqid('', true), -5);
23
John Parker

Les éléments suivants doivent fournir le moins de risques de duplication (vous pouvez remplacer mt_Rand() par une meilleure source de nombres aléatoires, par exemple à partir de /dev/*random ou à partir de GUID):

<?php
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $result = '';
    for ($i = 0; $i < 5; $i++)
        $result .= $characters[mt_Rand(0, 61)];
?>

MODIFIER:
Si vous êtes préoccupé par la sécurité, utilisez not avec Rand() ou mt_Rand(), et vérifiez que votre périphérique de données aléatoires est en réalité un périphérique générant des données random, et non un fichier normal ou quelque chose de prévisible, comme /dev/zero. mt_Rand() considéré comme nuisible:
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() :

<?php
    $length = 5;
    $randomBytes = openssl_random_pseudo_bytes($length);
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $charactersLength = strlen($characters);
    $result = '';
    for ($i = 0; $i < $length; $i++)
        $result .= $characters[ord($randomBytes[$i]) % $charactersLength];
?>
14
Archimedix

Vous pouvez l'essayer simplement comme ceci:

$length = 5;

$randomletter = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, $length);

plus de détails: http://forum.arnlweb.com/viewtopic.php?f=7&t=25

13
Apurba Pathak

Il semble que str_shuffle serait un bon usage pour cela . Graine le mélange avec les caractères souhaités.

$my_Rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);
6
Creeperstanson

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.

function randPass($length, $strength=8) {
    $vowels = 'aeuy';
    $consonants = 'bdghjmnpqrstvz';
    if ($strength >= 1) {
        $consonants .= 'BDGHJLMNPQRSTVWXZ';
    }
    if ($strength >= 2) {
        $vowels .= "AEUY";
    }
    if ($strength >= 4) {
        $consonants .= '23456789';
    }
    if ($strength >= 8) {
        $consonants .= '@#$%';
    }

    $password = '';
    $alt = time() % 2;
    for ($i = 0; $i < $length; $i++) {
        if ($alt == 1) {
            $password .= $consonants[(Rand() % strlen($consonants))];
            $alt = 0;
        } else {
            $password .= $vowels[(Rand() % strlen($vowels))];
            $alt = 1;
        }
    }
    return $password;
}
6
Kristoffer la Cour

Je ne savais pas non plus comment faire cela avant de penser à utiliser les balises PHP array. Et je suis à peu près 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:

function randstr ($len=10, $abc="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789") {
    $letters = str_split($abc);
    $str = "";
    for ($i=0; $i<=$len; $i++) {
        $str .= $letters[Rand(0, count($letters)-1)];
    };
    return $str;
};

Vous pouvez utiliser cette fonction comme ceci

randstr(20)     // returns a random 20 letter string
                // Or like this
randstr(5, abc) // returns a random 5 letter string using the letters "abc"
3
user8142790
$str = '';
$str_len = 8;
for($i = 0, $i < $str_len; $i++){
    //97 is ascii code for 'a' and 122 is ascii code for z
    $str .= chr(Rand(97, 122));
}
return $str
3
edrian

Si c'est bien que vous n'ayez que les lettres A à F, voici ma solution:

str_pad(dechex(mt_Rand(0, 0xFFFFF)), 5, '0', STR_PAD_LEFT);

Je crois que l’utilisation de fonctions de hachage est un excès pour une tâche aussi simple que celle de générer 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 une 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 la fiabilité de mt_Rand. Mersenne Twister est connu pour son caractère aléatoire de haute qualité, il convient donc parfaitement.

2
gronostaj

fonctionne bien dans PHP (PHP 5.4.4)

$seed = str_split('abcdefghijklmnopqrstuvwxyz');
$Rand = array_Rand($seed, 5);
$convert = array_map(function($n){
    global $seed;
    return $seed[$n];
},$Rand);

$var = implode('',$convert);
echo $var;

Démo en direct

1
Lyoniel Farase

Semblable à la réponse de Brad Christie , mais en utilisant sha1 alrorithm pour les caractères 0-9a-zA-Z et avec le préfixe aléatoire:

$str = substr(sha1(mt_Rand() . microtime()), mt_Rand(0,35), 5);

Mais si vous avez défini des caractères (autorisés):

$validChars = array('0','1','2' /*...*/,'?','-','_','a','b','c' /*...*/);
$validCharsCount = count($validChars);

$str = '';
for ($i=0; $i<5; $i++) {
    $str .= $validChars[Rand(0,$validCharsCount - 1)];
}

** METTRE &AGRAVE; JOUR **

Comme le souligne 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.

1
Yanick Rochon

Source: PHP Fonction générant des caractères aléatoires

Cette simple fonction PHP a fonctionné pour moi:

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;

}

Usage: 

echo cvf_ps_generate_random_code(5);
1
Carl

Voici mon random 5 cents ...

$random=function($a, $b) {
    return(
        substr(str_shuffle(('\\`)/|@'.
        password_hash(mt_Rand(0,999999),
        PASSWORD_DEFAULT).'!*^&~(')),
        $a, $b)
    );
};

echo($random(0,5));

La nouvelle fonction password_hash() (*> = PHP 5.5) de PHP permet de générer un nombre relativement long de caractères et de chiffres en majuscules et en minuscules. 

Deux concat. les chaînes avant et après password_hash dans la fonction $ random conviennent à un changement. 

Les paramètres de $random() * ($ a, $ b) sont en réalité des paramètres substr(). :)

NOTE: cela n’a pas besoin d’être une fonction, cela peut aussi bien être une variable normale .. comme un vilain singleliner, comme ceci:

$random=(substr(str_shuffle(('\\`)/|@'.password_hash(mt_Rand(0,999999), PASSWORD_DEFAULT).'!*^&~(')), 0, 5));

echo($random);
0
Spooky

J'ai toujours utiliser ceci:

<?php function fRand($len) {
    $str = '';
    $a = "abcdefghijklmnopqrstuvwxyz0123456789";
    $b = str_split($a);
    for ($i=1; $i <= $len ; $i++) { 
        $str .= $b[Rand(0,strlen($a)-1)];
    }
    return $str;
} ?>

Lorsque vous l'appelez, définit la longueur de la chaîne.

<?php echo fRand([LENGHT]); ?>

Vous pouvez également modifier les caractères possibles dans la chaîne $a.

0
LipESprY
function CaracteresAleatorios( $Tamanno, $Opciones) {
    $Opciones = empty($Opciones) ? array(0, 1, 2) : $Opciones;
    $Tamanno = empty($Tamanno) ? 16 : $Tamanno;
    $Caracteres=array("0123456789","abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    $Caracteres= implode("",array_intersect_key($Caracteres, array_flip($Opciones)));
    $CantidadCaracteres=strlen($Caracteres)-1;
    $CaracteresAleatorios='';
    for ($k = 0; $k < $Tamanno; $k++) {
        $CaracteresAleatorios.=$Caracteres[Rand(0, $CantidadCaracteres)];
    }
    return $CaracteresAleatorios;
}
0
John F