重複する可能性が最も少ない、正確に5つのランダムな文字列を作成します。それを行う最善の方法は何でしょうか?ありがとう。
Random::alphanumericString($length)
すると、暗号で保護されたランダムデータから供給される0-9a-zA-Zの文字列を取得できます。
重複する可能性が最も少ない、正確に5つのランダムな文字列を作成します。それを行う最善の方法は何でしょうか?ありがとう。
Random::alphanumericString($length)
すると、暗号で保護されたランダムデータから供給される0-9a-zA-Zの文字列を取得できます。
回答:
$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」になります
md5()
ただし、を使用した場合の問題は、16文字のセット(10桁a
からf
、つまり文字列文字ごとに4ビット)で構成される文字列が得られることです。これは、いくつかの目的には十分かもしれませんが、暗号化の目的には少なすぎる可能性があります(16シンボルのうち5文字= 16 ^ 5 = 20ビット= 1048576の可能性)。
array_rand($seed, 5)
値ではなく配列キーを返すため、コードは機能しません
"
、'
およびバックスラッシュで$charset
?これらの文字を含めるには、エスケープシーケンスを使用する必要がありますか?
$len
入力パラメーターも使用していません...忘れましたか?
for
ループが不足している場合は、次のように使用します。
$s = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
str_shuffle('ab')
を与えるab
かba
、しないがaa
。そのstr_repeat
ための許可を追加します。しかし、そうは言っても、私が与えた解決策は本当に深刻なものではありません...それは機能しますが。
l
、i
、1
、0
、O
、などと500のバウチャーのうちには、重複を得ませんでした。
次のように簡単に試すことができます。
$length = 5;
$randomletter = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, $length);
以下は、重複の可能性を最小限に抑える必要があります(GUID mt_rand()
から、/dev/*random
またはGUID からなど、より優れた乱数ソースに置き換えることをお勧めします)。
<?php
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$result = '';
for ($i = 0; $i < 5; $i++)
$result .= $characters[mt_rand(0, 61)];
?>
編集:
セキュリティに懸念がある場合は、実際にはorを使用せず、ランダムデータデバイスが実際にランダムデータを生成するデバイスであり、通常のファイルやなどの予測可能なものではないことを確認してください。有害と考えられる:https : //spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-phprand()
mt_rand()
/dev/zero
mt_rand()
編集:
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];
?>
strlen()
ループ内での使用は不要なオーバーヘッドです。特に、その間に文字セットが変更されないことがすでにわかっている場合はなおさらです。
私はいつも同じ機能を使って、通常はパスワードを生成します。使いやすく便利です。
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;
}
str_shuffleがこれに適しているようです。好きなキャラクターでシャッフルをシードします。
$my_rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);
AFの文字のみが表示される場合は、次の解決策があります。
str_pad(dechex(mt_rand(0, 0xFFFFF)), 5, '0', STR_PAD_LEFT);
ハッシュ関数を使用することは、ランダムな16進数字のシーケンスを生成するような単純なタスクではやりすぎだと思います。dechex
+ mt_rand
は同じ仕事をしますが、不必要な暗号化作業はしません。str_pad
出力文字列の長さが5文字であることを保証します(乱数が0x10000未満の場合)。
重複確率はmt_rand
の信頼性に依存します。メルセンヌツイスターは、高品質のランダム性で知られているため、タスクによく適合します。
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"
Brad Christieの回答に似ていますが、sha1
文字にアロリズムを使用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)];
}
** 更新 **
以下のようArchimedixが指摘組み合わせの数が指定された文字範囲のために低いので、これは「重複取得の少なくとも可能性」を返すように保証するものではありません。文字数を増やすか、文字列に余分な(特殊)文字を許可する必要があります。あなたの場合、最初の解決策が望ましいと思います。
time()
は、の最大100万倍予測可能ですmicrotime()
。
$str
。
˫§»⁋⅓
より安全であるためにそれらに「」を与えたくない...参照キーを7文字以上に増やす。(ところで:私の以前のコメントの訂正、それは5x36文字です)
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;
この単純な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);
ここに私の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つの連結。password_hash
$ random関数内の前後の文字列は変更に適しています。
以下のためのParamteres $random()
*($、$ b)は、実際にあるsubstr()
パラメータ。:)
注:これは関数である必要はありません。通常の変数でもかまいません。
$random=(substr(str_shuffle(('\\`)/|@'.password_hash(mt_rand(0,999999), PASSWORD_DEFAULT).'!*^&~(')), 0, 5));
echo($random);
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;
}
私は離れてこれを使います:
<?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-9a-zA-Z
か?