중복 될 가능성이 가장 적은 정확한 5 개의 임의 문자열을 만들고 싶습니다. 이를 수행하는 가장 좋은 방법은 무엇입니까? 감사.
Random::alphanumericString($length)
하면 암호화로 안전한 임의 데이터에서 가져온 0-9a-zA-Z 문자열을 가져올 수 있습니다.
중복 될 가능성이 가장 적은 정확한 5 개의 임의 문자열을 만들고 싶습니다. 이를 수행하는 가장 좋은 방법은 무엇입니까? 감사.
Random::alphanumericString($length)
하면 암호화로 안전한 임의 데이터에서 가져온 0-9a-zA-Z 문자열을 가져올 수 있습니다.
답변:
$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 개 기호 중 5 개 문자 = 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 에서 또는 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);
해시 함수를 사용하는 것은 임의의 16 진수 시퀀스를 생성하는 것과 같은 간단한 작업에 과잉이라고 생각합니다. 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"
유사 브래드 크리스티 의 대답하지만, 사용 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 자 이상으로 늘립니다. . (BTW : 내 이전 코멘트 교정, 그것은 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
있습니까?