str_shuffleによる方法~文字重複なし
概要
この方法の場合、
- ランダム文字列中の文字は全て異なる
- ランダム文字列の最大長は36文字
数字とアルファベットで36文字を使う場合、文字列長に対するパターン数は以下の通り(36!/(36-n)!)。
- 5文字→45,239,040通り(約45百万通り、107のオーダー)
- 10文字→922,393,263,052,800通り(約900兆通り、1014のオーダー)
- 16文字→152,901,072,685,905,223,680,000(約1500垓通り、1023のオーダー)
丁寧に書いた場合
コード
|
const RANDOM_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'; function random_string($length) { $shuffled_chars = str_shuffle(RANDOM_CHARS); $random_string = substr($shuffled_chars, 0, $length); return $random_string; } echo random_string(16), "\n"; // ogp1de2ma9i4szrk |
処理の流れ
- ランダム文字列に使う文字ソースの文字列を準備しておく。
const RANDOM_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
str_shuffle()
関数により、文字ソースの文字をシャッフルした文字列を得る($shuffled_chars
)。
substr()
関数により、シャッフルされた文字列の先頭から必要な文字数分を切り出す($random_string
)
1行で書いた場合
|
function random_string($length) { return substr(str_shuffle(RANDOM_CHARS), 0, $length); } |
確率
16文字のケースで考えると、1つのパターンが発生する確率はおおよそ1÷1.5×1023 = 6.54×10-23。
仮に1秒間に100万個のパターンが生成されるとすると、同じパターンの再帰年数は1/6.54×10-23÷106÷60÷60÷24÷365.25≒4.8×109年、約50億年になる。
str_shuffleによる方法~文字重複あり
概要
この方法の場合、
- ランダム文字列中に同じ文字が出現し得る
- ランダム文字列の長さは任意
数字とアルファベットで36文字を使う場合、文字列長に対するパターン数は以下の通り。
- 5文字→60,466,176通り(約6千万通り、107のオーダー)
- 10文字→3,656,158,440,062,976通り(約3600兆通り、1015のオーダー)
- 16文字→7,958,661,109,946,400,884,391,936(約8𥝱通り、1024のオーダー)
丁寧に書いた場合
コード
|
const RANDOM_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'; function random_string($length) { $chars = str_repeat(RANDOM_CHARS, $length); $random_chars = str_shuffle($chars); $random_string = substr($random_chars, 0, $length); return $random_string; } echo random_string(16), "\n"; // kudpwhftxmec6h35 |
処理の流れ
- ランダム文字列に使う文字ソースの文字列を準備しておく。
const RANDOM_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
- 文字ソースの文字列をランダム文字列の文字数分だけ繰り返した文字列を得る(
$chars
)。
- その文字列をシャッフルする(
$random_chars
)。
- シャッフルされた文字列の先頭から、ランダム文字列の文字数分だけ切出す(
$random_string
)。
1行で書いた場合
|
function random_string($length) { return substr(str_shuffle(str_repeat(RANDOM_CHARS, $length)), 0, $length); } |
確率
16文字のケースで考えると、1つのパターンが発生する確率はおおよそ1÷8×1024 = 1.25×10-25。
仮に1秒間に100万個のパターンが生成されるとすると、同じパターンの再帰年数は1/1.25×10-25÷106÷60÷60÷24÷365.25≒2.5×1011年、約2500億年になる。
array_mapによる方法~文字重複あり
概要
この方法による結果は、str_shuffleによる方法と等価。
丁寧に書いた場合
コード
|
const RANDOM_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'; function random_string($length) { $source_array = array_fill(0, $length, 0); $random_char = function($v) {return substr(RANDOM_CHARS, mt_rand(0, strlen(RANDOM_CHARS)-1), 1);}; $random_chars = array_map($random_char, $source_array); $random_string = implode($random_chars); return $random_string; } echo random_string(16), "\n"; // a9i78m8geshwta5s |
処理の流れ
- ランダム文字列に使う文字ソースの文字列を準備しておく。
const RANDOM_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'
- ランダム文字列のための配列を準備する(
$source_array
)。文字列長分の長さの配列を確保すればよいので、ここではarray_fill()
を使っている。
- 文字ソース文字列からランダムに1つの文字を返すコールバック関数を定義する(
$random_char
)。
- ランダム文字を要素とする配列を得る(
$random_chars
)。最初に準備した$source_array
の各要素にコールバックをマッピングしている。
['a', '9', 'i', ..., 's']
- ランダム文字配列を
implode()
関数で文字列に変換する($random_string
)。
1行で書いた場合
先のコードを1行で書くとこうなる。
|
function random_string($length) { return implode(array_map(function($v) { return substr(RANDOM_CHARS, mt_rand(0, strlen(RANDOM_CHARS)-1), 1);}, array_fill(0, $length, 0))); } |
1行が長くなりすぎるので複数行にすると以下のようになる。
|
function random_string($length) { return implode( array_map( function($v) { return substr(RANDOM_CHARS, mt_rand(0, strlen(RANDOM_CHARS)-1), 1); }, array_fill(0, $length, 0))); } |
確率
この方法による確率は、str_shuffle
による方法と同じ。