検証リンクで使用するために、数字と文字を使用してランダムで一意の文字列を生成するにはどうすればよいでしょうか? たとえば、Web サイトでアカウントを作成すると、リンクが記載されたメールが送信され、アカウントを確認するにはそのリンクをクリックする必要があります。
PHPを使用してそれらの1つを生成するにはどうすればよいですか?
検証リンクで使用するために、数字と文字を使用してランダムで一意の文字列を生成するにはどうすればよいでしょうか? たとえば、Web サイトでアカウントを作成すると、リンクが記載されたメールが送信され、アカウントを確認するにはそのリンクをクリックする必要があります。
PHPを使用してそれらの1つを生成するにはどうすればよいですか?
PHP 7 標準ライブラリは、random_bytes($length)
暗号的に安全な疑似ランダム バイトを生成する関数を提供します。
例:
$bytes = random_bytes(20);
var_dump(bin2hex($bytes));
上記の例では、次のようなものが出力されます。
string(40) "5fe69c95ed70a9869d9f9af7d8400a6673bb9ce9"
詳細: http://php.net/manual/en/function.random-bytes.php
PHP 5 (古い)
この同じ問題を解決する方法を調べていましたが、パスワードの取得にも使用できるトークンを関数で作成したいと考えています。これは、トークンが推測される能力を制限する必要があることを意味します。uniqid
時間に基づいているため、php.netによると「戻り値はmicrotime()とほとんどuniqid
変わらない」ため、基準を満たしていません。PHP では、openssl_random_pseudo_bytes()
代わりに を使用して暗号的に安全なトークンを生成することをお勧めします。
簡潔で簡潔な答えは次のとおりです。
bin2hex(openssl_random_pseudo_bytes($bytes))
これにより、長さ = $bytes * 2 の英数字のランダムな文字列が生成されます。残念ながら、これには のアルファベットしかありませんが、[a-f][0-9]
機能します。
function crypto_rand_secure($min, $max)
{
$range = $max - $min;
if ($range < 1) return $min; // not so random...
$log = ceil(log($range, 2));
$bytes = (int) ($log / 8) + 1; // length in bytes
$bits = (int) $log + 1; // length in bits
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
$rnd = $rnd & $filter; // discard irrelevant bits
} while ($rnd > $range);
return $min + $rnd;
}
function getToken($length)
{
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
$max = strlen($codeAlphabet); // edited
for ($i=0; $i < $length; $i++) {
$token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
}
return $token;
}
crypto_rand_secure($min, $max)
rand()
またはのドロップインとして機能しmt_rand
ます。openssl_random_pseudo_bytes を使用して、$min と $max の間の乱数を作成します。
getToken($length)
トークン内で使用するアルファベットを作成し、長さ の文字列を作成します$length
。
ソース: http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
セキュリティ通知: このソリューションは、ランダム性の品質がアプリケーションのセキュリティに影響を与える可能性がある状況では使用しないでください。特に、
rand()
とuniqid()
は、暗号的に安全な乱数ジェネレーターではありません。安全な代替手段については、スコットの回答を参照してください。
時間の経過とともに完全に一意である必要がない場合:
md5(uniqid(rand(), true))
それ以外の場合 (ユーザーの一意のログインを既に決定している場合):
md5(uniqid($your_user_login, true))
Scottの回答に基づいて、オブジェクト指向ソリューションを作成しました。
<?php
namespace Utils;
/**
* Class RandomStringGenerator
* @package Utils
*
* Solution taken from here:
* http://stackoverflow.com/a/13733588/1056679
*/
class RandomStringGenerator
{
/** @var string */
protected $alphabet;
/** @var int */
protected $alphabetLength;
/**
* @param string $alphabet
*/
public function __construct($alphabet = '')
{
if ('' !== $alphabet) {
$this->setAlphabet($alphabet);
} else {
$this->setAlphabet(
implode(range('a', 'z'))
. implode(range('A', 'Z'))
. implode(range(0, 9))
);
}
}
/**
* @param string $alphabet
*/
public function setAlphabet($alphabet)
{
$this->alphabet = $alphabet;
$this->alphabetLength = strlen($alphabet);
}
/**
* @param int $length
* @return string
*/
public function generate($length)
{
$token = '';
for ($i = 0; $i < $length; $i++) {
$randomKey = $this->getRandomInteger(0, $this->alphabetLength);
$token .= $this->alphabet[$randomKey];
}
return $token;
}
/**
* @param int $min
* @param int $max
* @return int
*/
protected function getRandomInteger($min, $max)
{
$range = ($max - $min);
if ($range < 0) {
// Not so random...
return $min;
}
$log = log($range, 2);
// Length in bytes.
$bytes = (int) ($log / 8) + 1;
// Length in bits.
$bits = (int) $log + 1;
// Set all lower bits to 1.
$filter = (int) (1 << $bits) - 1;
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
// Discard irrelevant bits.
$rnd = $rnd & $filter;
} while ($rnd >= $range);
return ($min + $rnd);
}
}
<?php
use Utils\RandomStringGenerator;
// Create new instance of generator class.
$generator = new RandomStringGenerator;
// Set token length.
$tokenLength = 32;
// Call method to generate random string.
$token = $generator->generate($tokenLength);
必要に応じて、カスタム アルファベットを使用できます。サポートされている文字を含む文字列をコンストラクターまたはセッターに渡すだけです。
<?php
$customAlphabet = '0123456789ABCDEF';
// Set initial alphabet.
$generator = new RandomStringGenerator($customAlphabet);
// Change alphabet whenever needed.
$generator->setAlphabet($customAlphabet);
SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa
それが誰かを助けることを願っています。乾杯!
UUID (Universally Unique Identifier) を使用でき、ユーザー認証文字列から支払いトランザクション ID まで、あらゆる目的に使用できます。
UUID は 16 オクテット (128 ビット) の数値です。標準形式では、UUID は 32 桁の 16 進数で表され、ハイフンで区切られた 5 つのグループに分けられ、8-4-4-4-12 の形式で合計 36 文字 (32 文字の英数字と 4 つのハイフン) で表されます。
function generate_uuid() {
return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
mt_rand( 0, 0xffff ),
mt_rand( 0, 0x0C2f ) | 0x4000,
mt_rand( 0, 0x3fff ) | 0x8000,
mt_rand( 0, 0x2Aff ), mt_rand( 0, 0xffD3 ), mt_rand( 0, 0xff4B )
);
}
//関数呼び出し
$transationID = generate_uuid();
いくつかの出力例は次のようになります。
E302D66D-87E3-4450-8CB6-17531895BF14
22D288BC-7289-442B-BEEA-286777D559F2
51B4DE29-3B71-4FD2-9E6C-071703E1FF31
3777C8C6-9FF5-4C78-AAA2-08A47F555E81
54B91C72-2CF4-4501-A6E9-02A60DCBAE4C
60F75C7C-1AE3-417B-82C8-14D456542CD7
8DE0168D-01D3-4502-9E59-10D665CEBCB2
将来誰かに役立つことを願っています:)
この関数は、数字と文字を使用してランダム キーを生成します。
function random_string($length) {
$key = '';
$keys = array_merge(range(0, 9), range('a', 'z'));
for ($i = 0; $i < $length; $i++) {
$key .= $keys[array_rand($keys)];
}
return $key;
}
echo random_string(50);
出力例:
zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8
私はこのワンライナーを使用します:
base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));
ここで、length は目的の文字列の長さです (4 で割り切れます。それ以外の場合は、4 で割り切れる最も近い数値に切り捨てられます)。
以下のコードを使用して、11 文字の乱数を生成するか、必要に応じて数を変更します。
$randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);
または、カスタム関数を使用して乱数を生成できます
function randomNumber($length){
$numbers = range(0,9);
shuffle($numbers);
for($i = 0;$i < $length;$i++)
$digits .= $numbers[$i];
return $digits;
}
//generate random number
$randomNum=randomNumber(11);
例 (疑似コード)
int myInt = random(0, numcharacters)
char[] codealphabet = 'ABCDEF12345'
char random = codealphabet[i]
repeat until long enough
本当にランダムな文字列の場合、次を使用できます
<?php
echo md5(microtime(true).mt_Rand());
出力:
40a29479ec808ad4bcff288a48a25d5c
そのため、まったく同時に文字列を複数回生成しようとしても、異なる出力が得られます。
検証リンクを扱うときは、ハッシュ キーを使用するのが好きです。マイクロタイムに基づいてハッシュするため、キーが同じである必要がある理由はないため、MD5 を使用するマイクロタイムとハッシュを使用することをお勧めします。
$key = md5(rand());
$key = md5(microtime());
function random_string($length = 8) {
$alphabets = range('A','Z');
$numbers = range('0','9');
$additional_characters = array('_','=');
$final_array = array_merge($alphabets,$numbers,$additional_characters);
while($length--) {
$key = array_rand($final_array);
$password .= $final_array[$key];
}
if (preg_match('/[A-Za-z0-9]/', $password))
{
return $password;
}else{
return random_string();
}
}
これが究極のユニークIDジェネレーターです。私が作った。
<?php
$d=date ("d");
$m=date ("m");
$y=date ("Y");
$t=time();
$dmt=$d+$m+$y+$t;
$ran= rand(0,10000000);
$dmtran= $dmt+$ran;
$un= uniqid();
$dmtun = $dmt.$un;
$mdun = md5($dmtran.$un);
$sort=substr($mdun, 16); // if you want sort length code.
echo $mdun;
?>
好きなように、ID の任意の「var」をエコーできます。ただし、$mdunの方が優れています。md5をsha1に置き換えてコードを改善できますが、それは非常に長くなり、必要ない場合があります。
ありがとうございました。
コップ一杯の水で窒息しているこの人々...
$random= substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*.-_"), 0, 10);
単純。このランダムな文字列の繰り返しの可能性は 0,00000000000000000000000000001^70 です
前の例を読んだ後、私はこれを思いつきました:
protected static $nonce_length = 32;
public static function getNonce()
{
$chars = array();
for ($i = 0; $i < 10; $i++)
$chars = array_merge($chars, range(0, 9), range('A', 'Z'));
shuffle($chars);
$start = mt_rand(0, count($chars) - self::$nonce_length);
return substr(join('', $chars), $start, self::$nonce_length);
}
配列[0-9、AZ]を10回複製し、要素をシャッフルします。substr()がより「創造的」になるランダムな開始点を取得した後:) [az]およびその他の要素を配列に追加して、複製することができます多かれ少なかれ、私よりも創造的である
私は常にこの関数を使用して、カスタムのランダムな英数字文字列を生成します...これが役立つことを願っています。
<?php
function random_alphanumeric($length) {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345689';
$my_string = '';
for ($i = 0; $i < $length; $i++) {
$pos = mt_rand(0, strlen($chars) -1);
$my_string .= substr($chars, $pos, 1);
}
return $my_string;
}
echo random_alphanumeric(50); // 50 characters
?>
たとえば、次のように生成されます。
別の文字列と比較して、それが一意のシーケンスであることを確認する場合は、このトリックを使用できます...
$string_1 = random_alphanumeric(50);
$string_2 = random_alphanumeric(50);
while ($string_1 == $string_2) {
$string_1 = random_alphanumeric(50);
$string_2 = random_alphanumeric(50);
if ($string_1 != $string_2) {
break;
}
}
echo $string_1;
echo "<br>\n";
echo $string_2;
2 つの一意の文字列を生成します。
qsBDs4JOoVRfFxyLAOGECYIsWvpcpMzAO9pypwxsqPKeAmYLOi
Ti3keE1WfGgTNxQVXtbNNbhhvvapnaUfGMVJecHkUjHbuCb85pF
これがあなたが探しているものであることを願っています...