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

2010年12月05日に質問されました。  ·  閲覧回数 1.3M回  ·  ソース

Captain Lightning picture
2010年12月05日

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

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

    RandomString();
    echo $randstring;

私は何が間違っているのですか?

回答

Stephen Watkins picture
2010年12月05日
1458

この質問に具体的に答えるには、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();

これにより、予測可能なランダムな文字列が生成されることに注意してください。

A. Cheshirov picture
2012年11月04日
380

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

もう1つの方法。

UPDATED (これで任意の長さの文字列が生成されます):

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

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

それでおしまい。 :)

Scott Arciszewski picture
2015年06月29日
354

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

シンプルで安全、そして正しい答えは、 RandomLibを使用し、車輪の再発明をしないことです。

独自のソリューションを発明することを主張する人のために、PHP 7.0.0はこの目的のためにrandom_int()を提供します。 まだPHP5.xを使用している場合は

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ください。random_compatが必要です)

Rudie picture
2014年09月05日
164

これにより、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
Humphrey picture
2013年02月10日
92

@tasmaniski:あなたの答えは私のために働いた。 私も同じ問題を抱えていたので、同じ答えを探している人に提案したいと思います。 これは@tasmaniskiからです:

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

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

rjmunro picture
2013年02月07日
46

アプリケーションによっては(パスワードを生成したかった)、

$string = base64_encode(openssl_random_pseudo_bytes(30));

base64であるため、要求された文字だけでなく、 =または-が含まれる場合があります。 より長い文字列を生成し、それをフィルタリングおよびトリミングしてそれらを削除することができます。

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

Kraang Prime picture
2014年04月20日
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文字のランダムな文字列の場合)。

Rathienth Baskaran picture
2012年09月25日
25

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

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エイリアスです。

Davor picture
2012年12月27日
25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

それなら!

Madan Sapkota picture
2020年01月25日
19

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