And*_*rew 359 php string random uniqueidentifier
如何使用数字和字母生成随机的唯一字符串以用于验证链接?就像您在网站上创建一个帐户一样,它会向您发送一封带有链接的电子邮件,您必须单击该链接才能验证您的帐户...是的......其中一个.
如何使用PHP生成其中一个?
更新:记住了uniqid()
.它是一个PHP函数,它根据当前时间(以微秒为单位)生成唯一标识符.我想我会用那个.
Sco*_*ott 475
我只是在研究如何解决同样的问题,但我也希望我的函数能够创建一个可用于密码检索的令牌.这意味着我需要限制令牌猜测的能力.因为uniqid
是基于时间的,并且根据php.net"返回值与microtime()略有不同",uniqid
不符合标准.PHP建议使用openssl_random_pseudo_bytes()
生成加密安全令牌.
一个快速,简短和重点的答案是:
bin2hex(openssl_random_pseudo_bytes($bytes))
Run Code Online (Sandbox Code Playgroud)
这将生成一个随机字符串的字母数字字符长度= $ 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;
}
Run Code Online (Sandbox Code Playgroud)
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
编辑(PHP7):随着PHP7的发布,标准库现在有两个新函数可以替换/改进/简化上面的crypto_rand_secure函数.random_bytes($length)
和random_int($min, $max)
http://php.net/manual/en/function.random-bytes.php
http://php.net/manual/en/function.random-int.php
例:
function getToken($length){
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
$max = strlen($codeAlphabet);
for ($i=0; $i < $length; $i++) {
$token .= $codeAlphabet[random_int(0, $max-1)];
}
return $token;
}
Run Code Online (Sandbox Code Playgroud)
小智 287
安全注意事项:在随机性质量会影响应用程序安全性的情况下,不应使用此解决方案.特别是,
rand()
并且uniqid()
不是加密安全的随机数生成器.请参阅斯科特关于安全替代方案的答案.
如果你不需要它随着时间的推移绝对独特:
md5(uniqid(rand(), true))
否则(假设您已为用户确定了唯一的登录名):
md5(uniqid($your_user_login, true))
Run Code Online (Sandbox Code Playgroud)
Sla*_* II 89
我根据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);
}
}
Run Code Online (Sandbox Code Playgroud)
<?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);
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以使用自定义字母.只需将带有受支持字符的字符串传递给构造函数或setter:
<?php
$customAlphabet = '0123456789ABCDEF';
// Set initial alphabet.
$generator = new RandomStringGenerator($customAlphabet);
// Change alphabet whenever needed.
$generator->setAlphabet($customAlphabet);
Run Code Online (Sandbox Code Playgroud)
SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa
Run Code Online (Sandbox Code Playgroud)
我希望它能帮助别人.干杯!
小智 31
此函数将使用数字和字母生成随机密钥:
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);
Run Code Online (Sandbox Code Playgroud)
示例输出:
zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8
Run Code Online (Sandbox Code Playgroud)
Dev*_*per 31
您可以使用UUID(通用唯一标识符),它可以用于任何目的,从用户身份验证字符串到支付交易ID.
UUID是16个八位字节(128位)的数字.在其规范形式中,UUID由32个十六进制数字表示,显示在由连字符分隔的五个组中,形式为8-4-4-4-12,总共36个字符(32个字母数字字符和四个连字符).
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 )
);
}
Run Code Online (Sandbox Code Playgroud)
//调用函数
$transationID = generate_uuid();
Run Code Online (Sandbox Code Playgroud)
一些示例输出将如下:
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
Run Code Online (Sandbox Code Playgroud)
希望它能帮助将来的某个人:)
Dud*_*ock 15
我用这个单线:
base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));
Run Code Online (Sandbox Code Playgroud)
其中length是所需字符串的长度(可被4整除,否则会向下舍入到最接近4的整数)
使用下面的代码生成11个字符的随机数,或根据您的要求更改数字.
$randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);
Run Code Online (Sandbox Code Playgroud)
或者我们可以使用自定义函数来生成随机数
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);
Run Code Online (Sandbox Code Playgroud)
例如(伪代码)
int myInt = random(0, numcharacters)
char[] codealphabet = 'ABCDEF12345'
char random = codealphabet[i]
repeat until long enough
Run Code Online (Sandbox Code Playgroud)
小智 7
对于真正随机的字符串,您可以使用
<?php
echo md5(microtime(true).mt_Rand());
Run Code Online (Sandbox Code Playgroud)
输出:
40a29479ec808ad4bcff288a48a25d5c
Run Code Online (Sandbox Code Playgroud)
因此,即使您尝试在完全相同的时间多次生成字符串,您也会得到不同的输出。
这是一个简单的函数,允许您生成包含字母和数字(字母数字)的随机字符串。您还可以限制字符串长度。这些随机字符串可用于各种目的,包括:推荐代码、促销代码、优惠券代码。函数依赖于以下 PHP 函数: base_convert、sha1、uniqid、mt_rand
function random_code($length)
{
return substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, $length);
}
echo random_code(6);
/*sample output
* a7d9e8
* 3klo93
*/
Run Code Online (Sandbox Code Playgroud)
尝试生成随机密码时,您正在尝试:
首先生成一组加密安全的随机字节
其次是将这些随机字节转换为可打印的字符串
现在,有多种方法可以在 php 中生成随机字节,例如:
$length = 32;
//PHP 7+
$bytes= random_bytes($length);
//PHP < 7
$bytes= openssl_random_pseudo_bytes($length);
Run Code Online (Sandbox Code Playgroud)
然后你想把这些随机字节变成一个可打印的字符串:
您可以使用bin2hex:
$string = bin2hex($bytes);
Run Code Online (Sandbox Code Playgroud)
或base64_encode:
$string = base64_encode($bytes);
Run Code Online (Sandbox Code Playgroud)
但是,请注意,如果使用 base64,则无法控制字符串的长度。您可以使用 bin2hex 来做到这一点,使用32 个字节将变成64 个字符的 string。但它只能在EVEN字符串中像这样工作。
所以基本上你可以这样做:
$length = 32;
if(PHP_VERSION>=7){
$bytes= random_bytes($length);
}else{
$bytes= openssl_random_pseudo_bytes($length);
}
$string = bin2hex($bytes);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
543022 次 |
最近记录: |