我想创建精确的5个随机字符串,并尽可能减少重复。最好的方法是什么?谢谢。
Random::alphanumericString($length)
您可以从加密安全的随机数据中获取带有0-9a-zA-Z的字符串。
我想创建精确的5个随机字符串,并尽可能减少重复。最好的方法是什么?谢谢。
Random::alphanumericString($length)
您可以从加密安全的随机数据中获取带有0-9a-zA-Z的字符串。
Answers:
$rand = substr(md5(microtime()),rand(0,26),5);
这将是我最好的猜测-除非您也要寻找特殊字符:
$seed = str_split('abcdefghijklmnopqrstuvwxyz'
.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.'0123456789!@#$%^&*()'); // and any other characters
shuffle($seed); // probably optional since array_is randomized; this may be redundant
$rand = '';
foreach (array_rand($seed, 5) as $k) $rand .= $seed[$k];
而且,对于基于时钟的时钟(由于它是递增的,因此冲突较少):
function incrementalHash($len = 5){
$charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$base = strlen($charset);
$result = '';
$now = explode(' ', microtime())[1];
while ($now >= $base){
$i = $now % $base;
$result = $charset[$i] . $result;
$now /= $base;
}
return substr($result, -5);
}
注意:增量意味着更容易猜测;如果您将其用作盐或验证令牌,请不要使用。盐(现在)为“ WCWyb”表示从现在起5秒钟为“ WCWyg”)
md5()
不过是,你得到了一个16字符集的字符串(10位和a
到f
,每串字符即4位)。对于某些目的,这可能就足够了,但对于密码目的而言可能太少了(16个符号中的五个字符= 16 ^ 5 = 20位= 1048576个可能性)。
array_rand($seed, 5)
将返回数组键,而不是值,因此您的代码将不起作用
"
,'
和反斜线$charset
?我是否需要使用转义序列来包含那些字符?
$len
输入参数...您忘了吗?
如果for
回路供不应求,这是我喜欢使用的方式:
$s = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
str_shuffle('ab')
愿意付出ab
,ba
但永远不会aa
。添加str_repeat
允许。但这就是说,我提供的解决方案虽然确实有效,但并不是真正的解决方案。
l
,i
,1
,0
,O
,等,并拿出500个券有没有重复。
您可以像这样简单地尝试:
$length = 5;
$randomletter = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, $length);
以下内容应提供最小的重复机会(您可能希望mt_rand()
用更好的随机数源代替,例如,来自/dev/*random
或来自GUID):
<?php
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$result = '';
for ($i = 0; $i < 5; $i++)
$result .= $characters[mt_rand(0, 61)];
?>
编辑:
如果您担心安全性,请不要使用rand()
或mt_rand()
,并确认您的随机数据设备实际上是生成随机数据的设备,而不是常规文件或可预测的东西/dev/zero
。mt_rand()
被认为是有害的:https :
//spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php
编辑:
如果您在PHP中具有OpenSSL支持,则可以使用openssl_random_pseudo_bytes()
:
<?php
$length = 5;
$randomBytes = openssl_random_pseudo_bytes($length);
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$charactersLength = strlen($characters);
$result = '';
for ($i = 0; $i < $length; $i++)
$result .= $characters[ord($randomBytes[$i]) % $charactersLength];
?>
strlen()
循环使用是不必要的开销,尤其是如果您已经知道字符集在此期间不会更改的话。
我总是为此使用相同的功能,通常会生成密码。它易于使用且有用。
function randPass($length, $strength=8) {
$vowels = 'aeuy';
$consonants = 'bdghjmnpqrstvz';
if ($strength >= 1) {
$consonants .= 'BDGHJLMNPQRSTVWXZ';
}
if ($strength >= 2) {
$vowels .= "AEUY";
}
if ($strength >= 4) {
$consonants .= '23456789';
}
if ($strength >= 8) {
$consonants .= '@#$%';
}
$password = '';
$alt = time() % 2;
for ($i = 0; $i < $length; $i++) {
if ($alt == 1) {
$password .= $consonants[(rand() % strlen($consonants))];
$alt = 0;
} else {
$password .= $vowels[(rand() % strlen($vowels))];
$alt = 1;
}
}
return $password;
}
似乎str_shuffle将是一个很好的用途。使用所需的任意字符播种随机播放。
$my_rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);
如果您只收到字母AF,那是我的解决方案:
str_pad(dechex(mt_rand(0, 0xFFFFF)), 5, '0', STR_PAD_LEFT);
我相信使用哈希函数对于生成一个随机十六进制数字序列这样的简单任务来说是多余的。dechex
+ mt_rand
将执行相同的工作,但是没有不必要的加密工作。str_pad
保证输出字符串的5个字符的长度(如果随机数小于0x10000)。
重复概率取决于mt_rand
的可靠性。Mersenne Twister以高质量的随机性而闻名,因此它应该非常适合这项任务。
在想到使用PHP之前,我也不知道该怎么做array
。而且我很确定这是用数组生成随机字符串或数字的最简单方法。代码:
function randstr ($len=10, $abc="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789") {
$letters = str_split($abc);
$str = "";
for ($i=0; $i<=$len; $i++) {
$str .= $letters[rand(0, count($letters)-1)];
};
return $str;
};
您可以像这样使用此功能
randstr(20) // returns a random 20 letter string
// Or like this
randstr(5, abc) // returns a random 5 letter string using the letters "abc"
与Brad Christie的答案类似,但sha1
对字符使用alrorithm 0-9a-zA-Z
并以随机值作为前缀:
$str = substr(sha1(mt_rand() . microtime()), mt_rand(0,35), 5);
但是,如果您设置了已定义的(允许的)字符:
$validChars = array('0','1','2' /*...*/,'?','-','_','a','b','c' /*...*/);
$validCharsCount = count($validChars);
$str = '';
for ($i=0; $i<5; $i++) {
$str .= $validChars[rand(0,$validCharsCount - 1)];
}
** 更新 **
正如Archimedix指出的那样,由于给定字符范围的组合数量很少,因此这不能保证返回“复制的可能性最小”。您将需要增加字符数,或在字符串中允许额外的(特殊)字符。我认为,在您的情况下,第一种解决方案会更可取。
time()
是可预测性的1百万倍microtime()
。
$str
。
˫§»⁋⅓
仅仅因为这样更安全就给他们“ ”,而是将参考密钥增加到7个或更多字符。(顺便说一句:我之前的评论中的更正,是5x36字符)
在PHP(php 5.4.4)中工作正常
$seed = str_split('abcdefghijklmnopqrstuvwxyz');
$rand = array_rand($seed, 5);
$convert = array_map(function($n){
global $seed;
return $seed[$n];
},$rand);
$var = implode('',$convert);
echo $var;
来源:生成随机字符的PHP函数
这个简单的PHP函数为我工作:
function cvf_ps_generate_random_code($length=10) {
$string = '';
// You can define your own characters here.
$characters = "23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
用法:
echo cvf_ps_generate_random_code(5);
这是我的random 5 cents
...
$random=function($a, $b) {
return(
substr(str_shuffle(('\\`)/|@'.
password_hash(mt_rand(0,999999),
PASSWORD_DEFAULT).'!*^&~(')),
$a, $b)
);
};
echo($random(0,5));
PHP的新功能password_hash()
(*> = PHP 5.5)正在完成生成相当长的大小写和数字字符集的工作。
两个连环。password_hash
$ random函数之前和之后的字符串都适合更改。
对于Paramteres $random()
*($ A,$ b)是实际substr()
参数。:)
注意:这不必是一个函数,它也可以是普通变量..作为一个讨厌的单件套,如下所示:
$random=(substr(str_shuffle(('\\`)/|@'.password_hash(mt_rand(0,999999), PASSWORD_DEFAULT).'!*^&~(')), 0, 5));
echo($random);
function CaracteresAleatorios( $Tamanno, $Opciones) {
$Opciones = empty($Opciones) ? array(0, 1, 2) : $Opciones;
$Tamanno = empty($Tamanno) ? 16 : $Tamanno;
$Caracteres=array("0123456789","abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ");
$Caracteres= implode("",array_intersect_key($Caracteres, array_flip($Opciones)));
$CantidadCaracteres=strlen($Caracteres)-1;
$CaracteresAleatorios='';
for ($k = 0; $k < $Tamanno; $k++) {
$CaracteresAleatorios.=$Caracteres[rand(0, $CantidadCaracteres)];
}
return $CaracteresAleatorios;
}
我已经使用此:
<?php function fRand($len) {
$str = '';
$a = "abcdefghijklmnopqrstuvwxyz0123456789";
$b = str_split($a);
for ($i=1; $i <= $len ; $i++) {
$str .= $b[rand(0,strlen($a)-1)];
}
return $str;
} ?>
调用时,设置字符串的长度。
<?php echo fRand([LENGHT]); ?>
您还可以更改字符串中可能的字符$a
。
0-9a-zA-Z
?