web-dev-qa-db-ja.com

ランダムな5文字の文字列を生成します

重複する可能性を最小限に抑えて、正確な5つのランダムな文字列を作成します。それを行う最善の方法は何でしょうか?ありがとう。

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

私の最善の推測でしょう-特別なキャラクターも探しているのでなければ:

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

そして、クロックに基づいたもの(インクリメンタルなので衝突が少ない):

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

注:増分は推測しやすいことを意味します。これをソルトまたは検証トークンとして使用している場合は、使用しないでください。 「WCWyb」の塩(現在)は、5秒後に「WCWyg」であることを意味します)

144
Brad Christie

forループが不足している場合、使用したいものは次のとおりです。

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

迅速な方法は、 niqid 関数の最も揮発性の高い文字を使用することです。

例えば:

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

次のように簡単に試すことができます:

$length = 5;

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

詳細: http://forum.arnlweb.com/viewtopic.php?f=7&t=25

18
Apurba Pathak

以下は、重複の可能性を最小限に抑える必要があります(mt_Rand()/dev/*randomまたはGUIDからのより良い乱数ソースに置き換えることができます):

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

編集:
セキュリティが心配な場合は、本当にnotRand()またはmt_Rand()を使用し、ランダムデータデバイスが実際にデバイスであることを確認してくださいrandomデータを生成します。通常のファイルや/dev/zeroのような予測可能なデータではありません。 mt_Rand()は有害と見なされます:
https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-Ruby-and-php

EDIT:PHPでOpenSSLをサポートしている場合は、 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

通常はパスワードを生成するために、これには常に同じ関数を使用します。使いやすく便利です。

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;
}
7

str_shuffleがこれに適しているようです。 Seed好きなキャラクターとシャッフル。

$my_Rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);
6
Creeperstanson
$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

A〜Fの文字だけを取得しても問題ない場合は、次のソリューションを使用します。

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

ハッシュ関数の使用は、ランダムな16進数のシーケンスを生成するような単純なタスクにとってはやり過ぎだと思います。 dechex + mt_Randは同じ仕事をしますが、不要な暗号化作業はありません。 str_padは、出力文字列の5文字の長さを保証します(乱数が0x10000より小さい場合)。

重複する確率は、mt_Randの信頼性に依存します。 Mersenne Twister は高品質のランダム性で知られているため、タスクにうまく適合するはずです。

2
gronostaj

PHP arrayを使用することを考えるまで、これを行う方法も知りませんでした。そして、これは配列を使用してランダムな文字列または数値を生成する最も簡単な方法であると確信しています。コード:

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;
};

この関数は次のように使用できます

randstr(20)     // returns a random 20 letter string
                // Or like this
randstr(5, abc) // returns a random 5 letter string using the letters "abc"
2
user8142790

でうまくいく 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;

ライブデモ

1
Lyoniel Farase

Brad Christie の答えと似ていますが、sha1 alrorithmを0-9a-zA-Zの文字に使用し、ランダムな値をプレフィックスとして使用します。

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

ただし、定義済みの(許可された)文字を設定している場合:

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

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

**UPDATE**

Archimedix が指摘したように、特定の文字範囲に対して組み合わせの数が少ないため、「複製される可能性が最も低い」ことを保証するものではありません。文字数を増やすか、文字列に余分な(特殊な)文字を許可する必要があります。あなたの場合、最初の解決策が望ましいと思います。

1
Yanick Rochon

ソース: ランダムな文字を生成するPHP関数

この単純なPHP関数は私のために働いた:

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;

}

使用法:

echo cvf_ps_generate_random_code(5);
1
Carl

ここに私の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));

PHPの新しいpassword_hash()(*> = PHP 5.5)関数は、大文字と小文字と数字のかなり長いセットを生成するジョブを実行しています。

2つの連結。 $ random関数内のpassword_hashの前後の文字列は変更に適しています。

$random() *($ a、$ b)のパラメーターは、実際にはsubstr()パラメーターです。 :)

注:これは関数である必要はありませんが、次のように1つの厄介なシングルライナーとして通常の変数にすることもできます。

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

echo($random);
0
Spooky

私はこれを使います:

<?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;
} ?>

呼び出すとき、文字列の長さを設定します。

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

文字列$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