Question

Comment serait-il possible de générer une chaîne aléatoire, unique en utilisant des nombres et des lettres pour une utilisation dans un lien vérifier? Comme lorsque vous créez un compte sur un site Web, et il vous envoie un e-mail avec un lien, et vous devez cliquer sur ce lien afin de vérifier votre compte ... ouais ... un.

Comment puis-je générer un de ceux qui utilisent PHP?

Mise à jour: uniqid() . Il est une fonction PHP qui génère un identifiant unique basé sur le temps actuel en microsecondes. Je pense que je vais l'utiliser.

Était-ce utile?

La solution

  

Avis de sécurité : Cette solution ne doit pas être utilisé dans des situations où la qualité de votre caractère aléatoire peut affecter la sécurité d'une application. En particulier, rand() et uniqid() ne sont pas cryptographiquement générateurs de nombres aléatoires sécurisés . Voir réponse de Scott pour une alternative sûre.

Si vous ne avez pas besoin d'être absolument unique au fil du temps:

md5(uniqid(rand(), true))

Dans le cas contraire (étant donné que vous avez déjà déterminé un login unique pour votre utilisateur):

md5(uniqid($your_user_login, true))

Autres conseils

Je viens de regarder sur la façon de résoudre ce même problème, mais je veux aussi ma fonction pour créer un jeton qui peut être utilisé pour la récupération de mot de passe ainsi. Cela signifie que je dois limiter la capacité du jeton à deviner. Parce que uniqid est basé sur le temps, et selon php.net « la valeur de retour est peu différent de microtime () », uniqid ne répond pas aux critères. PHP recommande d'utiliser openssl_random_pseudo_bytes() plutôt générer des jetons de sécurité cryptographique.

Un rapide, à court et à la réponse point est:

bin2hex(openssl_random_pseudo_bytes($bytes))

qui va générer une chaîne aléatoire de caractères alphanumériques de longueur = octets $ * 2. Malheureusement, cela a seulement un alphabet de [a-f][0-9], mais cela fonctionne.


Ci-dessous est la fonction la plus forte que je pourrais faire qui satisfait aux critères (Ceci est une version mise en œuvre de la réponse de Erik).

function crypto_rand_secure($min, $max)
{
    $range = $max - $min;
    if ($range < 1) return $min; // not so random...
    $log = ceil(log($range, 2));
    $bytes = (int) ($log / 8) + 1; // length in bytes
    $bits = (int) $log + 1; // length in bits
    $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
    do {
        $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
        $rnd = $rnd & $filter; // discard irrelevant bits
    } while ($rnd > $range);
    return $min + $rnd;
}

function getToken($length)
{
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
    }

    return $token;
}

crypto_rand_secure($min, $max) fonctionne comme une baisse de remplacement pour rand() ou mt_rand. Il utilise openssl_random_pseudo_bytes pour aider à créer un nombre aléatoire entre $ min et max $.

getToken($length) crée un alphabet à utiliser dans le jeton et crée ensuite une chaîne de $length de longueur.

EDIT: J'omis de citer la source - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322

EDIT (PHP7): Avec la sortie de PHP7, la bibliothèque standard dispose désormais de deux nouvelles fonctions qui peuvent remplacer / améliorer / simplifier la fonction crypto_rand_secure ci-dessus. random_bytes($length) et random_int($min, $max)

http://php.net/manual/en/function.random- bytes.php

http://php.net/manual/en/function.random- int.php

Exemple:

function getToken($length){
     $token = "";
     $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
     $codeAlphabet.= "0123456789";
     $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[random_int(0, $max-1)];
    }

    return $token;
}

version orientée objet des plus-voté solution

J'ai créé une solution orientée objet basée sur Scott La réponse de:

<?php

namespace Utils;

/**
 * Class RandomStringGenerator
 * @package Utils
 *
 * Solution taken from here:
 * http://stackoverflow.com/a/13733588/1056679
 */
class RandomStringGenerator
{
    /** @var string */
    protected $alphabet;

    /** @var int */
    protected $alphabetLength;


    /**
     * @param string $alphabet
     */
    public function __construct($alphabet = '')
    {
        if ('' !== $alphabet) {
            $this->setAlphabet($alphabet);
        } else {
            $this->setAlphabet(
                  implode(range('a', 'z'))
                . implode(range('A', 'Z'))
                . implode(range(0, 9))
            );
        }
    }

    /**
     * @param string $alphabet
     */
    public function setAlphabet($alphabet)
    {
        $this->alphabet = $alphabet;
        $this->alphabetLength = strlen($alphabet);
    }

    /**
     * @param int $length
     * @return string
     */
    public function generate($length)
    {
        $token = '';

        for ($i = 0; $i < $length; $i++) {
            $randomKey = $this->getRandomInteger(0, $this->alphabetLength);
            $token .= $this->alphabet[$randomKey];
        }

        return $token;
    }

    /**
     * @param int $min
     * @param int $max
     * @return int
     */
    protected function getRandomInteger($min, $max)
    {
        $range = ($max - $min);

        if ($range < 0) {
            // Not so random...
            return $min;
        }

        $log = log($range, 2);

        // Length in bytes.
        $bytes = (int) ($log / 8) + 1;

        // Length in bits.
        $bits = (int) $log + 1;

        // Set all lower bits to 1.
        $filter = (int) (1 << $bits) - 1;

        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));

            // Discard irrelevant bits.
            $rnd = $rnd & $filter;

        } while ($rnd >= $range);

        return ($min + $rnd);
    }
}

Utilisation

<?php

use Utils\RandomStringGenerator;

// Create new instance of generator class.
$generator = new RandomStringGenerator;

// Set token length.
$tokenLength = 32;

// Call method to generate random string.
$token = $generator->generate($tokenLength);

alphabet personnalisé

Vous pouvez utiliser l'alphabet personnalisé si nécessaire. Il suffit de passer une chaîne avec les caractères pris en charge au constructeur ou poseur:

<?php

$customAlphabet = '0123456789ABCDEF';

// Set initial alphabet.
$generator = new RandomStringGenerator($customAlphabet);

// Change alphabet whenever needed.
$generator->setAlphabet($customAlphabet);

VOICI les échantillons de sortie

SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa

J'espère que cela aidera quelqu'un. Vive!

Je suis en retard, mais je suis ici avec quelques bonnes données de recherche sur la base des fonctions fournies par la réponse de Scott . Je me suis donc une goutte océan numérique juste pour ce 5 jours test de longue automatisé et mis en mémoire les chaînes uniques générées dans une base de données MySQL.

Au cours de cette période d'essai, j'utilisé 5 différentes longueurs (5, 10, 15, 20, 50) et 0,5 million de +/- enregistrements ont été insérés pour chaque longueur. Au cours de mon test, seule la longueur 5 généré +/- 3K doubles sur 0,5 million et les longueurs restantes ne génère pas de doublons. On peut donc dire que si nous utilisons une longueur de 15 ou au-dessus avec les fonctions de Scott, nous pouvons générer des chaînes uniques très fiables. Voici le tableau montrant mes données de recherche:

Mise à jour: J'ai créé une application simple Heroku utilisant ces fonctions qui retourne le jeton comme une réponse JSON. L'application est accessible à https://uniquestrings.herokuapp.com/api/token? longueur = 15

J'espère que cette aide.

Cette fonction va générer une clé aléatoire en utilisant des nombres et des lettres:

function random_string($length) {
    $key = '';
    $keys = array_merge(range(0, 9), range('a', 'z'));

    for ($i = 0; $i < $length; $i++) {
        $key .= $keys[array_rand($keys)];
    }

    return $key;
}

echo random_string(50);

Exemple de sortie:

zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8

Vous pouvez utiliser UUID (Universally Unique Identifier), il peut être utilisé à des fins, de chaîne d'authentification utilisateur à numéro de transaction de paiement.

A UUID est un nombre de 16 octets (128 bits). Dans sa forme canonique, un UUID est représenté par 32 chiffres hexadécimaux, affiché dans cinq groupes séparés par des tirets, sous la forme 8-4-4-4-12 pour un total de 36 caractères (32 caractères alphanumériques et quatre tirets).

function generate_uuid() {
    return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
        mt_rand( 0, 0xffff ),
        mt_rand( 0, 0x0C2f ) | 0x4000,
        mt_rand( 0, 0x3fff ) | 0x8000,
        mt_rand( 0, 0x2Aff ), mt_rand( 0, 0xffD3 ), mt_rand( 0, 0xff4B )
    );

}

// appel funtion

$transationID = generate_uuid();

quelques sorties par exemple seront comme:

E302D66D-87E3-4450-8CB6-17531895BF14
22D288BC-7289-442B-BEEA-286777D559F2
51B4DE29-3B71-4FD2-9E6C-071703E1FF31
3777C8C6-9FF5-4C78-AAA2-08A47F555E81
54B91C72-2CF4-4501-A6E9-02A60DCBAE4C
60F75C7C-1AE3-417B-82C8-14D456542CD7
8DE0168D-01D3-4502-9E59-10D665CEBCB2

il aide quelqu'un l'espoir à l'avenir :)

J'utilise ce one-liner:

base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));

où la longueur est la longueur de la chaîne de caractères désirée (divisible par 4, sinon il obtient arrondi au plus proche nombre divisible par 4)

  1. Générer un nombre aléatoire en utilisant votre numéro préféré aléatoire Générateur
  2. multiplier et diviser pour obtenir un numéro correspondant au numéro de caractères dans l'alphabet de votre code
  3. Obtenir l'élément à l'index alphabet de votre code.
  4. Répéter de 1) jusqu'à ce que vous avez la longueur que vous veulent

par exemple (dans le pseudo-code)

int myInt = random(0, numcharacters)
char[] codealphabet = 'ABCDEF12345'
char random = codealphabet[i]
repeat until long enough

Utilisez le code ci-dessous pour générer le nombre aléatoire de 11 caractères ou modifier le nombre selon vos besoins.

$randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);

ou nous pouvons utiliser la fonction personnalisée pour générer le nombre aléatoire

 function randomNumber($length){
     $numbers = range(0,9);
     shuffle($numbers);
     for($i = 0;$i < $length;$i++)
        $digits .= $numbers[$i];
     return $digits;
 }

 //generate random number
 $randomNum=randomNumber(11);

Voici ultime générateur d'identification unique pour vous. faite par moi.

<?php
$d=date ("d");
$m=date ("m");
$y=date ("Y");
$t=time();
$dmt=$d+$m+$y+$t;    
$ran= rand(0,10000000);
$dmtran= $dmt+$ran;
$un=  uniqid();
$dmtun = $dmt.$un;
$mdun = md5($dmtran.$un);
$sort=substr($mdun, 16); // if you want sort length code.

echo $mdun;
?>

vous pouvez tout écho « var » pour votre identifiant que vous le souhaitez. mais mdun $ est mieux, vous pouvez remplacer md5 à SHA1 pour un meilleur code, mais ce sera très long qui peut vous ne avez pas besoin.

Merci.

Pour les chaînes très aléatoires, vous pouvez utiliser

<?php

echo md5(microtime(true).mt_Rand());

sorties:

40a29479ec808ad4bcff288a48a25d5c

même si vous essayez de générer chaîne plusieurs fois au même heure exacte, vous obtiendrez un résultat différent.

Voici ce que j'utilise:

md5(time() . rand());    
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b
function random_string($length = 8) {
    $alphabets = range('A','Z');
    $numbers = range('0','9');
    $additional_characters = array('_','=');
    $final_array = array_merge($alphabets,$numbers,$additional_characters);
       while($length--) {
      $key = array_rand($final_array);

      $password .= $final_array[$key];
                        }
  if (preg_match('/[A-Za-z0-9]/', $password))
    {
     return $password;
    }else{
    return  random_string();
    }

 }

Lorsque vous essayez de générer un mot de passe aléatoire que vous essayez de:

  • Tout d'abord générer un ensemble d'octets sécurisé cryptographiquement aléatoires

  • Second tourne les octets aléatoires dans une chaîne imprimable

Maintenant, il y a de façon multiple pour générer des octets aléatoires en php comme:

$length = 32;

//PHP 7+
$bytes= random_bytes($length);

//PHP < 7
$bytes= openssl_random_pseudo_bytes($length);

Alors, vous voulez transformer ces octets aléatoires dans une chaîne imprimable:

Vous pouvez utiliser bin2hex :

$string = bin2hex($bytes);

ou base64_encode :

$string = base64_encode($bytes);

Cependant, notez que vous ne contrôlez pas la longueur de la chaîne si vous utilisez base64. Vous pouvez utiliser bin2hex pour le faire, en utilisant 32 octets va se transformer en un 64 char string . Mais il ne fonctionnera donc comme dans une chaîne MÊME .

après avoir lu des exemples précédents, je suis venu avec ceci:

protected static $nonce_length = 32;

public static function getNonce()
{
    $chars = array();
    for ($i = 0; $i < 10; $i++)
        $chars = array_merge($chars, range(0, 9), range('A', 'Z'));
    shuffle($chars);
    $start = mt_rand(0, count($chars) - self::$nonce_length);
    return substr(join('', $chars), $start, self::$nonce_length);
}

dupliquer 10 fois le tableau [0-9, A-Z] et mélanger les éléments, après que je reçois un point de départ aléatoire pour substr () pour être plus « créative » :) vous pouvez ajouter [a-z] et d'autres éléments à tableau, en double plus ou moins, être plus créatif que moi

J'aime utiliser les clés de hachage lorsqu'ils traitent des liens de vérification. Je recommanderais d'utiliser le microtime et le hachage MD5 que l'utilisation car il devrait y avoir aucune raison pour que les clés doivent être les mêmes car il hachages hors du microtime.

  1. $key = md5(rand());
  2. $key = md5(microtime());

Ceci est une fonction simple qui vous permet de générer des chaînes aléatoires contenant des lettres et des chiffres (alphanumériques). Vous pouvez également limiter la longueur de la chaîne. Ces chaînes aléatoires peuvent être utilisés à des fins diverses, notamment: le code de référence, code promotionnel, le code de coupon. Fonction repose sur les fonctions suivantes PHP: base_convert, SHA1, uniqid, mt_rand

function random_code($length)
{
  return substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, $length);
}

echo random_code(6);

/*sample output
* a7d9e8
* 3klo93
*/

Si vous voulez générer une chaîne unique en PHP, essayez de suivre.

md5(uniqid().mt_rand());

Dans ce,

uniqid() - Il va générer chaîne unique. Cette fonction retourne identifiant unique en fonction d'horodatage en tant que chaîne.

mt_rand() -. Générer des nombres aléatoires

md5() -. Il va générer la chaîne de hachage

Scott, oui vous écrivez très bonne et solution! Merci.

Je suis également nécessaire pour générer jeton API unique pour mon chaque utilisateur. Ce qui suit est mon approche, je l'ai utilisé les informations utilisateur (nom d'utilisateur et code d'utilisateur):

public function generateUniqueToken($userid, $username){

        $rand = mt_rand(100,999);
    $md5 = md5($userid.'!(&^ 532567_465 ///'.$username);

    $md53 = substr($md5,0,3);
    $md5_remaining = substr($md5,3);

    $md5 = $md53. $rand. $userid. $md5_remaining;

    return $md5;
}

S'il vous plaît jeter un oeil et laissez-moi savoir si une amélioration que je peux faire. Merci

Voici ce que je me sers d'un de mes projets, il travaille beaucoup et il génère un UNIQUE RANDOM TOKEN :

$timestampz=time();

function generateRandomString($length = 60) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}


$tokenparta = generateRandomString();


$token = $timestampz*3 . $tokenparta;

echo $token;

S'il vous plaît noter que je multipliai l'horodatage par trois pour créer une confusion pour quiconque utilisateur peut se demander comment ce jeton est généré;)

J'espère que cela aide:)

Je pense que c'est la meilleure méthode à utiliser.

str_shuffle(md5(rand(0,100000)))
<?php
function generateRandomString($length = 11) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;

}

?>

fonction ci-dessus vous générer une chaîne aléatoire qui est la longueur de 11 caractères.

nous pouvons utiliser ce deux lignes de code pour générer chaîne unique ont testé environ 10.000.000 fois l'itération

  $sffledStr= str_shuffle('abscdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+');
    $uniqueString = md5(time().$sffledStr);

Je l'utilise toujours ma fonction pour générer une chaîne alphanumérique aléatoire sur mesure ... Hope this aide.

<?php
  function random_alphanumeric($length) {
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345689';
    $my_string = '';
    for ($i = 0; $i < $length; $i++) {
      $pos = mt_rand(0, strlen($chars) -1);
      $my_string .= substr($chars, $pos, 1);
    }
    return $my_string;
  }
  echo random_alphanumeric(50); // 50 characters
?>

Il génère par exemple: Y1FypdjVbFCFK6Gh9FDJpe6dciwJEfV6MQGpJqAfuijaYSZ86g

Si vous voulez comparer avec une autre chaîne pour être sûr est une séquence unique, vous pouvez utiliser cette astuce ...

$string_1 = random_alphanumeric(50);
$string_2 = random_alphanumeric(50);
while ($string_1 == $string_2) {
  $string_1 = random_alphanumeric(50);
  $string_2 = random_alphanumeric(50);
  if ($string_1 != $string_2) {
     break;
  }
}
echo $string_1;
echo "<br>\n";
echo $string_2;

il génère deux chaînes uniques:

qsBDs4JOoVRfFxyLAOGECYIsWvpcpMzAO9pypwxsqPKeAmYLOi

Ti3kE1WfGgTNxQVXtbNNbhhvvapnaUfGMVJecHkUjHbuCb85pF

L'espoir est ce que vous cherchez ...

Je crois que le problème avec toutes les idées existantes est qu'elles sont probablement unique, mais pas définitivement uniques (comme indiqué dans la réponse de Dariusz Walczak à loletech). J'ai une solution qui est en fait unique. Il exige que votre script ont une sorte de mémoire. Pour moi, c'est une base de données SQL. Vous pouvez aussi simplement écrire dans un fichier quelque part. Il y a deux implémentations:

Première méthode: avoir deux champs plutôt que 1 qui fournissent l'unicité. Le premier champ est un numéro d'identification qui ne sont pas aléatoires mais est unique (le premier ID est égal à 1, le second 2, ...). Si vous utilisez SQL, il suffit de définir le champ ID avec la propriété AUTO_INCREMENT. Le deuxième champ est pas unique mais est aléatoire. Cela peut être généré avec l'une des autres techniques personnes ont déjà mentionnées. L'idée de Scott était bonne, mais md5 est pratique et probablement assez bon pour la plupart des cas:

$random_token = md5($_SERVER['HTTP_USER_AGENT'] . time());

Deuxième méthode: Au fond la même idée, mais d'abord choisir un nombre maximum de chaînes qui sera jamais généré. Cela pourrait juste être un très gros chiffre comme un billion de dollars. Ensuite, faites la même chose, générer un ID, mais zéro pad pour que tous les ID sont le même nombre de chiffres. Ensuite, il suffit concaténer l'ID de la chaîne aléatoire. Il sera assez aléatoire pour la plupart des cas, mais la section d'identification veillera à ce que c'est aussi unique.

Vous pouvez utiliser ce code, J'espère que ce sera utile pour vous.

function rand_code($len)
{
 $min_lenght= 0;
 $max_lenght = 100;
 $bigL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 $smallL = "abcdefghijklmnopqrstuvwxyz";
 $number = "0123456789";
 $bigB = str_shuffle($bigL);
 $smallS = str_shuffle($smallL);
 $numberS = str_shuffle($number);
 $subA = substr($bigB,0,5);
 $subB = substr($bigB,6,5);
 $subC = substr($bigB,10,5);
 $subD = substr($smallS,0,5);
 $subE = substr($smallS,6,5);
 $subF = substr($smallS,10,5);
 $subG = substr($numberS,0,5);
 $subH = substr($numberS,6,5);
 $subI = substr($numberS,10,5);
 $RandCode1 = str_shuffle($subA.$subD.$subB.$subF.$subC.$subE);
 $RandCode2 = str_shuffle($RandCode1);
 $RandCode = $RandCode1.$RandCode2;
 if ($len>$min_lenght && $len<$max_lenght)
 {
 $CodeEX = substr($RandCode,0,$len);
 }
 else
 {
 $CodeEX = $RandCode;
 }
 return $CodeEX;
}

Détails sur générateur de code aléatoire en PHP

Code Scotts ci-dessus Simplifier en supprimant des boucles inutiles qui ralentit mal et ne le rend pas plus sûr que d'appeler openssl_random_pseudo_bytes juste une fois

function crypto_rand_secure($min, $max)
{
 $range = $max - $min;
 if ($range < 1) return $min; // not so random...
 $log = ceil(log($range, 2));
 $bytes = (int) ($log / 8) + 1; // length in bytes
 $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
 return $min + $rnd%$range;
}

function getToken($length)
{
 return bin2hex(openssl_random_pseudo_bytes($length)
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top