PHPランダム文字列ジェネレータ


814

私はPHPでランダムな文字列を作成しようとしていますが、これではまったく出力が得られません。

<?php
    function RandomString()
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $randstring = '';
        for ($i = 0; $i < 10; $i++) {
            $randstring = $characters[rand(0, strlen($characters))];
        }
        return $randstring;
    }

    RandomString();
    echo $randstring;

何が悪いのですか?


241
短い文字列を生成するための1行のソリューションはsubstr(md5(rand())、0、7);です。幸運...
tasmaniski

5
@tasmaniski ..あなたの解決策は大丈夫です。あなたの例では、生成できるランダムな文字列の数は整数のサイズによって制限されます。(2 ^ 32)最大で。他のソリューションの場合、(62 ^ 8)を生成できます。より大きな文字列が必要な場合、個別の文字列の数は最大2 ^ 32のままですが、それは(62 ^ N)に増加する他の解決策は..
マヌー

9
新しく生成された各文字を文字列に追加するのを忘れていました。そのまま上書きするだけです。$ randstring。= $ characters ..
Spock

3
@CaptainLightning受け入れられた回答をより安全なものに交換していただけませんか?:)
Scott Arciszewski

2
strlen($characters)=> strlen($characters) - 1-文字列の長さは1から始まります
Zippp 2017

回答:


1393

この質問に具体的に回答するには、2つの問題があります。

  1. $randstring エコーするときは範囲外です。
  2. 文字がループで一緒に連結されていません。

修正を加えたコードスニペットを次に示します。

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

以下の呼び出しでランダムな文字列を出力します。

// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();

これにより、予測可能なランダム文字列が生成されることに注意してください。安全なトークンを作成する場合は、この回答を参照してください


34
@FranciscoPresencia、ループの比較条件でメソッドを呼び出すときのように、余分な変数を「無駄にする」方がよいでしょう。
Rico Sonntag 2013

200
すべてのその仕事、好きな理由だけではない何かsubstr(str_shuffle(MD5(microtime())), 0, 10);
SpYk3HH 2014

4
コードをお寄せいただきありがとうございます。に変更rand()してくださいmt_rand()。私はあなたの方法を使用して、名前との衝突のトンを経験しました。
2014

5
@FranciscoPresenciaあなたはそれがどれほど恐ろしく非効率的であるかについて何か考えがありますか?文字列の長さを反復ごとに2回チェックしています。ループに入る前に、ループ内のstrlenも変数にキャッシュする必要があります。
developerbmw

4
これは良い解決策ではありません。これが生成する文字列は予測可能です。:(
スコットArciszewski 2015年

370

注:str_shuffle()内部的にを使用rand()しているため、暗号化の目的には適していません(ランダムパスワードの生成など)。代わりに安全な乱数ジェネレータが必要です。また、文字を繰り返すこともできません。

もう一つの方法。

UPDATED (これにより、任意の長さの文字列が生成されます):

function generateRandomString($length = 10) {
    return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}

echo  generateRandomString();  // OR: generateRandomString(24)

それでおしまい。:)


64
最短の回答の場合は+1 :)。しかし、すべてのユースケースに最適な答えではありません。このコードは、各文字が2回以上出現しない文字列を出力するため(ブルートフォース攻撃に対して弱くなります)、62文字を超える文字は出力されません。
David

17
これを行わないでください。非常に弱いです。ランダムな文字列を長くすると、弱くなります。
Abhi Beckert 2013

23
弱いかもしれませんが、すばやく簡単です。ユースケースにもよりますが、これは問題ありません。セキュリティや強度が必要なかったので使用しました。ただの速射シャッフル。私は単体テストを書いています。これにより、テストに適したランダムな入力が得られます。
SDC 2013年

23
@FranciscoPresenciaが安全でない理由は、同じ文字を2回使用しないためです。それはそれをひどいパスワードジェネレーターにします。誰もがこれに投票するのをやめてください、それは完全に安全ではないので決して使用されるべきではありません。パスワードが長くなると、以前に使用した文字をテストする必要がないため、ブルートフォースでテストする必要のある文字数が短くなります。
Abhi Beckert 2013

8
@FranciscoPresencia:これをランダムパスワードに使用しないようにすることについてのコメントをサポートします。しかし、私はこの答えがプラスワンであってはならないことに同意しません。ランダムな文字列を生成するための効果的な1行のソリューション(この質問の元のトピック)であるため、このオプションをプラスワンしました。
bwright 2013

331

この質問に対する答えはたくさんありますが、暗号的に安全な疑似乱数ジェネレータ(CSPRNG)を利用するものはありません。

シンプルで安全、かつ正しい答えは、RandomLibを使用し、ホイールを再発明しないことです。

独自のソリューションの開発を主張する人のために、PHP 7.0.0はrandom_int()この目的を提供します。まだPHP 5.xを使用している場合は、PHP 5のポリフィルを作成したrandom_int()ため、PHP 7にアップグレードする前でも新しいAPIを使用できます。

PHPでランダムな整数を安全に生成することは簡単なことではありません。自社開発のアルゴリズムを本番環境にデプロイする前に、常駐のStackExchange暗号化の専門家に常に確認する必要があります

安全な整数ジェネレータを用意すれば、CSPRNGを使用してランダムな文字列を生成することは、公園の散歩です。

安全なランダム文字列の作成

/**
 * Generate a random string, using a cryptographically secure 
 * pseudorandom number generator (random_int)
 *
 * This function uses type hints now (PHP 7+ only), but it was originally
 * written for PHP 5 as well.
 * 
 * For PHP 7, random_int is a PHP core function
 * For PHP 5.x, depends on https://github.com/paragonie/random_compat
 * 
 * @param int $length      How many characters do we want?
 * @param string $keyspace A string of all possible characters
 *                         to select from
 * @return string
 */
function random_str(
    int $length = 64,
    string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
): string {
    if ($length < 1) {
        throw new \RangeException("Length must be a positive integer");
    }
    $pieces = [];
    $max = mb_strlen($keyspace, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $pieces []= $keyspace[random_int(0, $max)];
    }
    return implode('', $pieces);
}

使用法

$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');
$c = random_str();

デモhttps : //3v4l.org/IMJGF(PHP 5の失敗は無視してください。random_compatが必要です)


3
関数の冒頭で$keyspace = str_shuffle($keyspace );セキュリティを強化
Jevgenij Dmitrijev

13
「セキュリティ強化」とはどういう意味ですか?安全な乱数ジェネレータをすでに使用しています。
Scott Arciszewski 2017

5
@JGEstiot安全にランダムな文字列を作成するには、暗号的に安全なランダム性が必要です。「PHPでランダムな文字列を生成する方法」を検索する人は、安全でない回答よりも安全な回答の方が適しています。
Scott Arciszewski 2018年

1
@ Scott Arciszewskiランダムな文字列を作成するたびに、暗号的にランダムな文字列を作成する必要はありません。問題はランダム化された文字列の作成に関するもので、これはセキュリティとは何の関係もありません。文字列はセキュリティ上重要なコンテキストで使用されると想定し、質問の核心を阻止する複雑さの層を追加しました。
JG Estiot 2018年

45
random_int()代わりに使用しrand()たりmt_rand()、開発者に複雑さを追加したりしません。同時に、セキュリティが強化されます。迅速なソリューションを求めてStackOverflowに来た人は、自分が構築しているものが安全である必要があるかどうかわからないかもしれません。デフォルトで安全な回答を提供すると、たとえそれが完全に偶然であったとしても、彼らはより安全なインターネットを作成します。この目標に反対する理由は私には謎です。
Scott Arciszewski

156

これにより、20文字の16進数文字列が作成されます。

$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars

PHP 7では(random_bytes()):

$string = base64_encode(random_bytes(10)); // ~14 characters, includes /=+
// or
$string = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes(32))), 0, 32); // 32 characters, without /=+
// or
$string = bin2hex(random_bytes(10)); // 20 characters, only 0-9a-f

openssl_random_pseudo_bytes()PHP 5.6までは、暗号学的に強力なアルゴリズムを使用していなかったことに注意してください。関連バグ:bugs.php.net/bug.php
id

また、これが作成できる最小の文字列の長さは2であることに注意してください。1以下のバイト長を渡した場合、openssl_random_pseudo_bytes()何も返されません。また、使用しているときというのノートbin2hex(openssl_random_pseudo_bytes($length / 2))あなたが整数で作業しているので、それが自動的にモジュロを削除し、2そうの次に低い倍数を使用しますが、$length = 19長さ18の文字列を生成します
ネイサンF.

それを使用して開くことができるファイルコンテンツとして、fgets($fp, 1024)および非常に長い行で問題があるすべてのファイルエディターとして使用するための提案:ワンライナーを返すかどうかにfunction string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }設定$splitnullます。それにより、どちらの場合にも使用できます。
mgutt 2017年

私はPHP 7のrandom_bytesソリューションが本当に好きですが、文字列を特定の文字数にする必要がある場合は、このようなものでしょうか?$string = substr(base64_encode(random_bytes($size)), 0, $size);
Programster

これは間違いなく最善の解決策です。スペースを取らず、非常にわかりやすい。
マシューキャンベル、

92

@tasmaniski:あなたの答えがうまくいきました。私は同じ問題を抱えていたので、同じ答えを探している人たちにそれを提案します。これは@tasmaniskiからです:

<?php 
    $random = substr(md5(mt_rand()), 0, 7);
    echo $random;
?>

これは、乱数を作成する方法を示すYouTubeビデオです


6
文字列がランダムな整数のみに基づいている場合、ランダムな整数を使用しないのはなぜですか?それらは、それをハッシュすることによってさらに深くなることはありません...そしてあなたのハッシュをカットすることによって、実際にあなたが始めなければならなかった小さなエントロピーを減少させます。
Surrican 2014

4
md530文字の制限になり、常に小文字になることに注意してください。
fyrye 2014年

3
さらに、rand()を暗号化に使用しないでください。暗号的に健全な文字列を生成したい場合は、openssl_random_pseudo_bytesを使用してください。
mattkgross 2015

md5(rand())可能な値は2 ^ 32のみです。これは、平均して、2 ^ 16個のランダムな文字列が繰り返されると予想されることを意味します。
Scott Arciszewski、2015年

2
まあ..私はOPが「安全にランダムな文字列」について話しているのではないでしょう。このソリューションはコンパクトで、簡単で、覚えやすく、適切なユースケースに適しています。そして、衝突の可能性に対処する必要がある場合は、ランダムな文字列にタイムスタンプを付加/追加してみませんか?:)
Erenor Paz 2016

46

アプリケーションに応じて(パスワードを生成したかった)、次を使用できます

$string = base64_encode(openssl_random_pseudo_bytes(30));

BASE64なので、彼らは含まれていてもよい=か、-要求された文字をなど。より長い文字列を生成し、それをフィルタリングおよびトリミングしてそれらを削除できます。

openssl_random_pseudo_bytesPHPで適切な乱数を生成するための推奨される方法のようです。なぜrand使用/dev/randomしないのかわかりません。


2
randは/ dev / urandomを使用しません。これは、posixのような環境でのみ使用でき、移植性がないためです。
MacroMan、2014年

3
@MacroManしかしopenssl_random_pseudo_bytes() 移植可能です。
ジャック

余分なbase64文字を削除する場合は、これを試してください:gist.github.com/zyphlar/7217f566fc83a9633959
willbradley

3
これは間違いではありませんが、不要な文字を破棄する方法には注意が必要です。たとえば、PHPリーグのOAuth2サーバーこのプルリクエストを確認してください。
Scott Arciszewski、2015

これは最良の答えの1つです。残念ですが、それ以上のサポートはありません。不要な文字をより適切に処理するために、回答を編集することをお勧めします。
jcuenod

28

これは、スクリプトレベルのループやOpenSSLライブラリの使用なしで真のランダム文字列を生成する単純なワンライナーです。

echo substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))), 1, 10);

それを分解してパラメーターを明確にする

// Character List to Pick from
$chrList = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

// Minimum/Maximum times to repeat character List to seed from
$chrRepeatMin = 1; // Minimum times to repeat the seed string
$chrRepeatMax = 10; // Maximum times to repeat the seed string

// Length of Random String returned
$chrRandomLength = 10;

// The ONE LINE random command with the above variables.
echo substr(str_shuffle(str_repeat($chrList, mt_rand($chrRepeatMin,$chrRepeatMax))), 1, $chrRandomLength);

このメソッドは、文字リストをランダムに繰り返すことによって機能し、結合された文字列をシャッフルして、指定された文字数を返します。

あなたは、さらに交換、返される文字列の長さをランダム化することによって、これをランダム化することができ$chrRandomLengthmt_rand(8, 15)(8と15文字の間でランダムな文字列の場合)。


申し訳ありませんが、1人のキャラクターが選択された場合、再び発生する確率は、プールに残っている他のキャラクターほど高くありません。ここに真のランダム性はありません...
Surrican '13

@TheSurrican-あなたはそのステートメントで間違っているでしょう。このアルゴリズムを使用すると、すべての文字が等しい確率を持つため、真にランダムです。これは、chrList文字列$ chrRepeatMaxを繰り返すことによって保証され、ランダム性を決定するstr_shuffleで魔法が実際に発生します。
Kraang Prime 2015

すべての文字は一度だけ出現し、ブルートフォース推測が非常に発生しやすい
venimus

@venimus不正解です。char文字列は、必要な数の文字だけ複製されます($chrRepeatMaxおよびを参照$chrRepeatMin)。したがって、10文字の文字列は(可能性は低いですが可能です)、「aaaaaaaaaa」になる可能性があります。
Kraang Prime

@SanuelJacksonすみません、コメントミスしました。私は間違った答えにコメントを付けました。あなたが正しいです!私はあなたの「トリック」を実際に使用しましたが、それは役に立たないIMHOなので、mt_randは使用しませんでした。エントロピーは増加しません。max-lengthでconstを使用しただけです。
venimus

25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

多田!


sha140文字に制限され、常に小文字になることに注意してください。
fyrye 2014年

3
sha1文字列はランダムではありません。特定の文字が他よりも頻繁に発生します。パスワードのように本当にランダム性が必要な場合にこれを使用するのは賢明ではありません。
キットSunde 2014

1
@KitSunde-はい、shaはランダムではなく、rand()はランダムです。そして、shaはここで必要とされるもののために完全に大丈夫です。OPは暗号レベルのランダム性を必要としません。
Davor、2015年

@Davor rant()がランダムであっても、shaが均等に分散されていなくても問題ありません。不均一な分布からランダムに選択すると、まったく同じ不均一な分布になります。私が強調しているのは「暗号レベル」のランダム性ではありませんrand()。受け入れられた答えのように、均等な分布から引き抜くのに必要な労力は最小限で、rand()と同じくらいランダムです。
キットSunde、2015年

@KitSunde-文字通り結局違いはありません。それがまさに、オーバーエンジニアリングと金メッキの定義です。
Davor、2015年

24

この関数を実装するより良い方法は次のとおりです。

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

    $key = "";
    for($i=0; $i < $length; $i++) {
        $key .= $keys[mt_rand(0, count($keys) - 1)];
    }
    return $key;
}

echo RandomString(20);

mt_rand応じて、よりランダムであり、この、この PHP 7のrand機能はの別名ですmt_rand


1
注意:mt_rand暗号で保護された値は生成されません。そのためには、PHP7 random_intまたはを使用する必要がありますrandom_bytes
jchook

18

$randstring関数スコープ内では、それを呼び出すスコープと同じではありません。戻り値を変数に割り当てる必要があります。

$randstring = RandomString();
echo $randstring;

または、戻り値を直接エコーします。

echo RandomString();

また、関数には少し間違いがあります。forループ内では、.=各文字が文字列に追加されるように使用する必要があります。を使用=すると、追加するのではなく、新しい文字ごとに上書きされます。

$randstring .= $characters[rand(0, strlen($characters))];

14

まず、使用するアルファベットを定義します。

$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special  = '~!@#$%^&*(){}[],./?';
$alphabet = $alphanum . $special;

次に、を使用openssl_random_pseudo_bytes()して適切なランダムデータを生成します。

$len = 12; // length of password
$random = openssl_random_pseudo_bytes($len);

最後に、このランダムデータを使用してパスワードを作成します。各文字なので$random可能chr(0)になるまではchr(255)、コードが付き、その序数値の除算後に余りを使用し$alphabet_lengthてくださいアルファベットの文字だけが選ばれている(やっては非常にランダムにバイアスをかけることに注意してください)を作成するには:

$alphabet_length = strlen($alphabet);
$password = '';
for ($i = 0; $i < $len; ++$i) {
    $password .= $alphabet[ord($random[$i]) % $alphabet_length];
}

別の方法として、一般的には、RandomLibSecurityLibを使用することをお勧めします。

use SecurityLib\Strength;

$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new Strength(Strength::MEDIUM));

$password = $generator->generateString(12, $alphabet);

モジュロ演算子%を使用すると、偏った出力が生成されます。ただし、RandomLibの強い+1。車輪を再発明しないでください。
Scott Arciszewski、2015年

1
D:うん、新しいrandom_int()関数はいいです
ジャック

11

短いメソッド...

ランダムな文字列を生成する最も簡単な方法は次のとおりです

<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15); 

echo substr(md5(rand()), 0, 7);

echo str_shuffle(MD5(microtime()));
?>

10

私はそこで最も人気のある関数のパフォーマンスをテストしました。私のボックスで32シンボルの1'000'000文字列を生成するのに必要な時間は次のとおりです。

2.5 $s = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,32);
1.9 $s = base64_encode(openssl_random_pseudo_bytes(24));
1.68 $s = bin2hex(openssl_random_pseudo_bytes(16));
0.63 $s = base64_encode(random_bytes(24));
0.62 $s = bin2hex(random_bytes(16));
0.37 $s = substr(md5(rand()), 0, 32);
0.37 $s = substr(md5(mt_rand()), 0, 32);

どれだけ長くかかったかは重要ではありませんが、どちらがより遅く、どちらがより速いかは重要なので、暗号化の準備など、要件に応じて選択できます。

MD5の周りのsubstr()は、32シンボルより短い文字列が必要な場合の正確性のために追加されました。

答えとして、文字列は連結されずに上書きされ、関数の結果は保存されませんでした。


私はその最良の答えだと思います。ありがとう!
NSukonny

10

PHP 7+ random_bytes関数を使用して、暗号で保護されたランダムバイトを生成します。

$bytes = random_bytes(16);
echo bin2hex($bytes);

可能な出力

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ openssl_random_pseudo_bytes関数を使用して疑似ランダムバイトを生成します。

$bytes = openssl_random_pseudo_bytes(16);
echo bin2hex($bytes);

可能な出力

e2d1254506fbb6cd842cd640333214ad


最高のユースケースは、可能性があり

function getRandomBytes($length = 16)
{
    if (function_exists('random_bytes')) {
        $bytes = random_bytes($length / 2);
    } else {
        $bytes = openssl_random_pseudo_bytes($length / 2);
    }
    return bin2hex($bytes);
}
echo getRandomBytes();

可能な出力

ba8cc342bdf91143


これは、指定された長さの文字列を生成しません
Timberman

@Timbermanそれは正確な長さを生成します。
Madan Sapkota

9

非常に簡単な方法の1つは、次のようなことです。

substr(md5(rand()),0,10);

これにより、10文字の長さのランダム文字列が生成されます。もちろん、計算面では少し重いと言う人もいるかもしれませんが、現在、プロセッサーはmd5またはsha256アルゴリズムを非常に高速に実行するように最適化されています。そしてもちろん、rand()関数が同じ値を返した場合、結果は同じになり、1/32767の確率で同じになります。セキュリティに問題がある場合は、次のように変更rand()しますmt_rand()


7
function rndStr($len = 64) {
     $randomData = file_get_contents('/dev/urandom', false, null, 0, $len) . uniqid(mt_rand(), true);
     $str = substr(str_replace(array('/','=','+'),'', base64_encode($randomData)),0,$len);
    return $str;
}

4
これは移植できません。これをposix以外の環境で実行しようとすると、致命的なエラーが発生します。
ブライアンエイジ2014


6

Laravel 5フレームワークのヘルパー関数

/**
 * Generate a "random" alpha-numeric string.
 *
 * Should not be considered sufficient for cryptography, etc.
 *
 * @param  int  $length
 * @return string
 */
function str_random($length = 16)
{
    $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}

4
「暗号化などには十分ではない」これは強く強調されるべきです。
Scott Arciszewski、2015年


4

関数の編集されたバージョンは問題なく動作しますが、問題が1つだけあります。$文字を囲むために間違った文字を使用したため、 '文字が生成されるランダム文字列の一部になることがあります。

これを修正するには、以下を変更します。

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

に:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

この方法では、囲まれた文字のみが使用され、 '文字は生成されるランダムな文字列の一部にはなりません。


4

別のワンライナー。文字と数字を含む10文字のランダムな文字列を生成します。range(2番目のパラメーターを調整してサイズを設定する)で配列を作成し、この配列をループしてランダムなASCII文字(範囲0〜9またはa〜z)を割り当て、配列を分解して文字列を取得します。

$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));

注:これはPHP 5.3以降でのみ機能します


最後に、32ビットのランダムな整数またはシャッフルされた文字列の肥大化したハッシュではなく、真にランダムなソリューション...
Surrican

たった1つの問題があります。数字は文字と同じくらい発生する可能性があり、私がそれを望んでいるほどランダムではありません。とにかくこのページで最良の解決策のための+1。それとその完璧を微調整します。
The Surrican

微調整...このように?rand(0, 57-48+122-97)<57-48?...:...?:)
vp_arth 2015年

4

一発ギャグ。

独自性のある巨大なストリングには高速です。

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}

md5(rand())乱数を生成するための恐ろしく安全でない方法です。
Scott Arciszewski、2015年

1
Xの長さといくつかの一意性を持つ文字列が意図されています。真のランダム性は意図されていません。
Jacob Smith


3

openssl_random_pseudo_bytesを使用した最後のコメントは気に入りましたが、不要な文字を削除する必要があり、長さの設定された文字列を取得できなかったため、これは解決策ではありませんでした。これが私の解決策です...

function rndStr($len = 20) {
    $rnd='';
    for($i=0;$i<$len;$i++) {
        do {
            $byte = openssl_random_pseudo_bytes(1);
            $asc = chr(base_convert(substr(bin2hex($byte),0,2),16,10));
        } while(!ctype_alnum($asc));
        $rnd .= $asc;
    }
    return $rnd;
}

3
function randomString($length = 5) {
    return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}

3

これは、「1」と「l」、「O」と「0」などの似ている文字を除いて、使いやすいランダムパスワードを生成する簡単な1行のソリューションです。ここでは5文字ですが、簡単にできますもちろん変更してください:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);

これは、後でjqueryで呼び出すランダムなID文字列を作成するのに最適です。IDKは、その良い習慣ですが、これは、受け入れられた回答のようなforを使用せずに私を大いに助けました...
Rodrigo Zuluaga

3

これが別の解決策です。

function genRandomString($length = 10)
{
    if($length < 1)
        $length = 1;
    return substr(preg_replace("/[^A-Za-z0-9]/", '', base64_encode(openssl_random_pseudo_bytes($length * 2))), 0, $length);
}

PS。UbuntuでPHP 7.2を使用しています。


2

PHPでランダムな文字列を生成する別の方法は次のとおりです。

function RandomString($length) {
    $original_string = array_merge(range(0,9), range('a','z'), range('A', 'Z'));
    $original_string = implode("", $original_string);
    return substr(str_shuffle($original_string), 0, $length);
}
echo RandomString(6);

2

真の一意のランダムキーを取得する方法は次のとおりです。

$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;

time()はUnixタイムスタンプであり、上記の他のランダムと比較して常に一意であるため、使用できます。次に、そのmd5sumを生成し、生成されたMD5から必要な長さを取得できます文字列ます。この例では10文字を使用していますが、もっとユニークにしたい場合は、より長い文字列を使用できます。

これがお役に立てば幸いです。


2
もちろん、time()一意とはほど遠いです。現在の秒が終了するまで、同じ値を繰り返し返します。ここで実際にいくつかのランダム性を提供するのstr_shuffle()は、残りのコードが文字を選択するサンプルを減らすだけです。
アルバロ・ゴンサレス

1
基本的には、32ビット整数をシャッフルします。ここではエントロピーはそれほど多くありません...
2014

2
攻撃者は、返される値time()(タイムスタンプのみ)を推測できます。これは、ランダム性の弱いソースです。
AL

2

PHPネイティブ関数のみを使用してパラメーター化されたワンライナー、PHP 5.1.0以降で機能

str_shuffle(implode('', (array_intersect_key(($map =  array_map('chr', array_merge(array_map('mt_rand', array_fill(0, $length = 25, 48), array_fill(0,$length,57)),array_map('mt_rand', array_fill(0, $length, 65), array_fill(0,$length,90)),array_map('mt_rand', array_fill(0, $length, 97), array_fill(0,$length,122))))), array_flip($keys = array_rand($map, $length))))))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.