PHP 랜덤 문자열 생성기


814

PHP에서 무작위 문자열을 만들려고하는데 다음과 같은 결과가 전혀 없습니다.

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

    RandomString();
    echo $randstring;

내가 무엇을 잘못하고 있지?


241
짧은 문자열을 생성하는 한 줄 해결책은 substr (md5 (rand ()), 0, 7); 행운을 빌어 요 ...
tasmaniski

5
@tasmaniski .. 귀하의 솔루션은 괜찮습니다. 그러나 덜 무작위입니다! 귀하의 예에서 생성 할 수있는 임의의 문자열 수는 정수 크기에 의해 제한됩니다. (2 ^ 32) 최대 .. 다른 솔루션의 경우 (62 ^ 8)을 생성 할 수 있습니다. 더 큰 문자열을 원할 경우 고유 문자열 수가 최대 2 ^ 32에 남아 있지만 다른 솔루션은 (62 ^ n)로 증가합니다.
마누

9
새로 생성 된 각 문자를 문자열에 추가하는 것을 잊었습니다. 당신은 그대로 그대로 덮어 쓰고 있습니다. $ randstring이어야합니다. = $ characters ..
Spock

3
@CaptainLightning보다 안전한 답변 중 하나에 대해 허용 된 답변을 바꿔 주시겠습니까? :)
Scott Arciszewski

2
strlen($characters)=> strlen($characters) - 1-문자열 길이는 1
Zippp로

답변:


1393

이 질문에 구체적으로 대답하기 위해 두 가지 문제가 있습니다.

  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();

예측 가능한 임의 문자열이 생성됩니다. 보안 토큰을 만들려면 이 답변을 참조하십시오 .


34
@FranciscoPresencia, 루프의 비교 조건에서 메소드를 호출 할 때 추가 변수를 "낭비"하는 것이 좋습니다.
Rico Sonntag

200
그 모든 것이 효과가있는 이유는 무엇 substr(str_shuffle(MD5(microtime())), 0, 10);입니까?
SpYk3HH

4
코드를 주셔서 감사합니다,하지만 제발 변화 rand()mt_rand(). 나는 당신의 방법을 사용하고 경험 t 이름 충돌을.
Nate

5
@FranciscoPresencia 얼마나 끔찍한 비효율적인지 아십니까? 반복 당 문자열 길이를 두 번 확인하고 있습니다! 루프 내부의 strlen은 루프에 들어가기 전에 변수에 캐시되어야합니다.
developerbmw

4
이것은 좋은 해결책이 아닙니다. 이것이 생성하는 문자열은 예측 가능합니다. :(
Scott Arciszewski 2016 년

370

참고 : str_shuffle()내부적으로를 사용하는데 rand(), 이는 암호화 목적에 적합하지 않습니다 (예 : 임의의 비밀번호 생성). 대신 안전한 난수 생성기 를 원합니다 . 또한 문자를 반복 할 수 없습니다.

한 가지 더

업데이트 됨 (이제 문자열 길이를 생성 함) :

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

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

그게 다야. :)


64
가장 짧은 답변은 +1입니다. :). 그러나 모든 사용 사례에 가장 적합한 것은 아닙니다. 이 코드는 각 문자가 두 번 이상 나타나지 않는 (따라서 무차별 대입 공격의 경우 약 해짐) 문자열을 출력하고 62자를 초과하는 문자는 출력하지 않습니다.
David

17
이 작업을 수행하지 마십시오. 매우 약합니다. 임의의 줄을 길게 만들수록 줄이 약해집니다.
Abhi Beckert

23
약할 수도 있지만 빠르고 쉽습니다. 유스 케이스에 따라 이것은 괜찮습니다. 보안이나 힘이 필요하지 않기 때문에 사용했습니다. 빠른 셔플. 단위 테스트를 작성 중이며 테스트 할 임의의 입력이 적절합니다.
SDC

23
@FranciscoPresencia 그것이 안전하지 않은 이유는 같은 문자를 두 번 사용하지 않기 때문입니다. 그것은 끔찍한 암호 생성기입니다. 모두가 투표를 중단하십시오. 완전히 안전하지 않아야합니다. 암호가 길어질수록 이전에 사용한 문자를 테스트하지 않으므로 무차별 적으로 테스트해야하는 문자 수가 줄어 듭니다.
Abhi Beckert

8
@FranciscoPresencia : 임의 암호에 이것을 사용하지 않는 것에 대한 귀하의 의견을지지합니다. 그러나 나는이 대답이 플러스 일이되어서는 안된다는 것에 동의하지 않습니다. 임의의 문자열 (이 질문의 원래 주제)을 생성하는 효과적인 한 줄 솔루션 이므로이 옵션을 플러스 1로 사용했습니다.
bwright

331

이 질문에 대한 답은 많지만 그 중 어느 것도 CSPRNG ( Cryptographically Secure Pseudo-Random Number Generator )를 사용하지 않습니다.

간단하고 안전하며 정답은 RandomLib 을 사용 하고 바퀴를 재발 명하지 않는 것입니다.

여러분 자신의 솔루션을 발명해야한다고 주장하는 사람들을 위해 PHP 7.0.0 random_int()이이 목적 을 제공 할 것입니다. 아직 PHP 5.x 를 사용하고 있다면 PHP 5 폴리 필을random_int() 작성 하여 PHP 7로 업그레이드하기 전에도 새로운 API를 사용할 수 있습니다.

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://3v4l.org/IMJGF (PHP 5 실패 무시, random_compat 필요)


3
기능의 시작 부분에 $keyspace = str_shuffle($keyspace );더 많은 보안을 위해 추가
Jevgenij Dmitrijev

13
"보안 강화"란 무엇을 의미합니까? 우리는 이미 안전한 난수 생성기를 사용하고 있습니다.
Scott Arciszewski

5
@JGEstiot 안전하게 임의의 문자열을 만들려면 암호로 안전한 임의성이 필요합니다. "PHP에서 임의의 문자열을 생성하는 방법"을 검색하는 사람은 안전하지 않은 답변보다 안전한 답변을 사용하는 것이 좋습니다.
Scott Arciszewski

1
@ Scott Arciszewski 임의의 문자열을 생성 할 때마다 암호로 임의의 문자열을 생성 할 필요는 없습니다. 문제는 무작위 문자열 생성에 관한 것이며 보안과는 아무런 관련이 없습니다. 문자열이 보안에 민감한 컨텍스트에서 사용될 것으로 가정하고 질문의 핵심을 방해하는 복잡한 계층을 추가합니다.
JG Estiot

45
random_int()대신 사용 rand()하거나 mt_rand()개발자에게 복잡성을 추가하지 않습니다. 동시에 보안을 강화합니다. 빠른 솔루션을 찾는 StackOverflow에 온 사람들은 자신이 구축하고있는 것이 안전해야하는지 알 수 없습니다. 우리가 기본적으로 안전한 답변을 제공한다면, 비록 그들이보기에는 완전히 우연이더라도 더 안전한 인터넷을 만듭니다. 이 목표에 반대하는 이유는 저에게 미스터리입니다.
Scott Arciszewski

155

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

주의하시기 바랍니다 openssl_random_pseudo_bytes()PHP 5.6까지 강력한 암호화 알고리즘을 사용하지 않았다. 관련 버그 : bugs.php.net/bug.php?id=70014
acidtv

이것으로 만들 수있는 가장 작은 문자열의 길이는 2입니다. 1 이하의 바이트 길이를 전달 openssl_random_pseudo_bytes()하면 아무것도 반환되지 않습니다. 또한 bin2hex(openssl_random_pseudo_bytes($length / 2))정수로 작업하기 때문에 사용 하면 모듈로가 자동으로 제거되고 2의 가장 낮은 배수를 사용합니다. 따라서 $length = 19길이가 18 인 문자열이 생성됩니다.
Nathan F.

열 수있는 파일 내용 fgets($fp, 1024)및 매우 긴 줄에 문제가있는 모든 파일 편집기 로 사용하는 제안 : 한 줄 을 반환해야하는지 여부로 function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }설정 $split합니다 null. 이를 통해 두 경우 모두에 사용할 수 있습니다.
mgutt

PHP 7의 random_bytes 솔루션이 정말 마음에 들지만 문자열을 특정 수의 문자로 사용해야하는 경우 다음과 같이 작동합니까? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programster

이것은 의심의 여지없이 최고의 솔루션입니다. 공간을 거의 차지하지 않으며 이해하기 매우 쉽습니다.
Matthew Campbell

92

@tasmaniski : 당신의 대답이 저에게 효과적이었습니다. 나는 같은 문제가 있었고 같은 대답을 찾는 사람들에게 그것을 제안 할 것입니다. 다음은 @tasmaniski에서 온 것입니다.

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

다음은 임의의 숫자를 만드는 방법을 보여주는 YouTube 비디오입니다.


6
문자열이 임의의 정수만을 기반으로하는 경우 왜 임의의 정수를 사용하지 않습니까? 그들은 건초 더미를 해시함으로써 더 깊어지지 않습니다 ... 해시를 자르면 실제로 시작해야 할 작은 엔트로피가 사라집니다.
Surrican

4
명심 md530 자로 제한하고 항상 소문자가 발생합니다.
fyrye

3
또한 rand ()는 암호화에 사용해서는 안됩니다. crypographically sound string을 생성하려면 openssl_random_pseudo_bytes를 사용하십시오 .
mattkgross

md5(rand())2 ^ 32 가능한 값만 제공합니다. 이것은 평균적으로 2 ^ 16 개의 임의의 문자열이 반복 된 후에 예상된다는 것을 의미합니다.
Scott Arciszewski 2016 년

2
음 .. 나는 OP가 "안전하게 임의의 문자열"에 대해 이야기하지 않는 것이 틀림 없다. 이 솔루션은 올바른 사용 사례에 맞게 작고 기억하기 쉽고 작습니다 . 충돌 가능성을 처리해야하는 경우 임의 문자열에 타임 스탬프를 추가 / 추가하지 않는 이유는 무엇입니까? :)
Erenor Paz

46

귀하의 응용 프로그램에 따라 (암호를 생성하고 싶었습니다)

$string = base64_encode(openssl_random_pseudo_bytes(30));

base64이므로 요청 된 문자를 포함 =하거나 포함 할 수 있습니다 -. 더 긴 문자열을 생성 한 다음 필터링하고 잘라서 제거 할 수 있습니다.

openssl_random_pseudo_bytesPHP에서 적절한 난수를 생성하는 권장 방법 인 것 같습니다. 왜 rand사용 /dev/random하지 않는지 모르겠습니다.


2
rand는 / dev / urandom을 사용하지 않습니다. 왜냐하면 환경과 같은 posix에서만 사용할 수 있고 이식성이 없기 때문입니다.
MacroMan

3
@MacroMan 그러나이 openssl_random_pseudo_bytes() 입니다 휴대용.
Ja͢ck

여분의 base64 문자를 제거하려면 다음을 시도하십시오. gist.github.com/zyphlar/7217f566fc83a9633959
willbradley

3
이것은 잘못된 것이 아니지만 원하지 않는 문자를 버리는 방법에주의를 기울일 것입니다. 예를 들어 PHP 리그의 OAuth2 서버에서이 풀 요청을 참조하십시오 .
Scott Arciszewski

이것은 최고의 답변 중 하나입니다. 안타깝게도 더 이상 지원하지 않습니다. 원치 않는 문자를 더 잘 처리하기 위해 답을 편집하는 것이 좋습니다.
jcuenod

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 자 사이의 임의의 문자열).


유감스럽게도 한 캐릭터가 선택되면 다시 등장 할 확률은 다른 캐릭터가 풀에 남아있는 것만 큼 높지 않습니다. 여기에 진정한 임의성이 없습니다.
Surrican

@TheSurrican-당신은 그 진술에서 틀릴 것입니다. 이 알고리즘을 사용하면 모든 문자가 동일한 확률을 가지므로 실제로 무작위입니다. 이것은 chrList 문자열 $ chrRepeatMax를 반복함으로써 보장되며 마법은 실제로 임의성을 결정하는 str_shuffle에서 발생합니다.
Kraang Prime

모든 문자는 한 번만 나타나며
무차별

@venimus 잘못되었습니다. char 문자열은 원하는만큼 많은 문자로 복제됩니다 ( $chrRepeatMax및 참조 $chrRepeatMin). 따라서 10 개의 char 문자열은 "아아아 아아아"일 수 있습니다.
Kraang Prime

@SanuelJackson 죄송합니다. 댓글이 없습니다. 나는 틀린 대답에 의견을 달았습니다. 당신이 맞아요! 나는 실제로 "트릭"을 사용했지만 쓸모없는 IMHO이기 때문에 mt_rand를 사용하지 않았습니다. 엔트로피에 추가되지 않습니다. max-length와 함께 const를 사용했습니다.
venimus

25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

타다!


명심 sha140 자로 제한하고 항상 소문자가 발생합니다.
fyrye

3
sha1 문자열은 무작위가 아니며 특정 문자가 다른 문자보다 자주 발생합니다. 암호와 같이 무작위를 원하는 경우에는 이것을 사용하지 않는 것이 좋습니다.
Kit Sunde

1
@KitSunde-예, sha는 무작위가 아니며 rand ()는 임의입니다. 그리고 sha는 여기에 필요한 것에 완벽하게 적합합니다. OP에는 암호화 수준의 임의성이 필요하지 않습니다.
Davor

@Davor rant()는 무작위로 sha가 골고루 분포되지 않은 경우 중요하지 않습니다. 고르지 않은 분포에서 무작위로 선택하면 정확히 같은 고르지 못한 분포가 나타납니다. 내가 강조하고있는 것은 "암호 수준"임의의 무작위가 아닙니다. 그렇다면 rand()어느 것도 사용해서는 안됩니다 . 허용 된 답변과 같이 균일 한 분포에서 뽑아내는 데 최소한의 노력이 필요하며 rand ()만큼 합리적입니다.
Kit Sunde

@ KitSunde-말 그대로 아무런 차이가 없습니다. 그것은 정확히 오버 엔지니어링과 금도금의 정의입니다.
Davor

24

이 기능을 구현하는 더 좋은 방법은 다음과 같습니다.

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_randPHP 7에서 이것이것 에 따르면 더 무작위 rand입니다 mt_rand. 함수는의 별칭입니다 .


1
주의 : mt_rand암호로 안전한 값을 생성하지 않습니다. 이를 위해서는 PHP7 random_int또는 을 사용해야합니다 random_bytes.
jchook

18

$randstring함수 범위에서 호출하는 범위와 동일하지 않습니다. 반환 값을 변수에 할당해야합니다.

$randstring = RandomString();
echo $randstring;

또는 반환 값을 직접 반향하십시오.

echo RandomString();

또한 함수에서 약간의 실수가 있습니다. for 루프 내에서 .=각 문자가 문자열에 추가되도록 사용해야 합니다. 를 사용 =하면 추가하는 대신 새 문자로 덮어 쓰게됩니다.

$randstring .= $characters[rand(0, strlen($characters))];

14

먼저 사용하려는 알파벳을 정의하십시오.

$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special  = '~!@#$%^&*(){}[],./?';
$alphabet = $alphanum . $special;

그런 다음 openssl_random_pseudo_bytes()적절한 무작위 데이터를 생성 하는 데 사용하십시오 .

$len = 12; // length of password
$random = openssl_random_pseudo_bytes($len);

마지막으로이 임의의 데이터를 사용하여 비밀번호를 만듭니다. 각 문자 때문에 $random될 수 있습니다 chr(0)때까지 chr(255), 코드와의 순서 값의 분할 후 나머지를 사용하여 $alphabet_length반드시 알파벳 문자 만이 선택됩니다 (그렇게하는 임의성을 바이어스합니다)를 만드는 :

$alphabet_length = strlen($alphabet);
$password = '';
for ($i = 0; $i < $len; ++$i) {
    $password .= $alphabet[ord($random[$i]) % $alphabet_length];
}

또는 RandomLibSecurityLib 를 사용하는 것이 일반적으로 더 좋습니다 .

use SecurityLib\Strength;

$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new Strength(Strength::MEDIUM));

$password = $generator->generateString(12, $alphabet);

모듈로 연산자 %를 사용하면 바이어스 출력이 생성됩니다. 그러나 RandomLib의 경우 +1이 강합니다. 바퀴를 재발 명하지 마십시오.
Scott Arciszewski 2016 년

1
네, 새로운 random_int () 함수는 훌륭합니다 : D
Ja͢ck

11

짧은 방법 ..

무작위 문자열을 생성하는 가장 짧은 방법은 다음과 같습니다.

<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15); 

echo substr(md5(rand()), 0, 7);

echo str_shuffle(MD5(microtime()));
?>

10

가장 인기있는 기능의 성능을 테스트했으며 상자에 32 개의 기호로 1'000'000 문자열을 생성하는 데 필요한 시간은 다음과 같습니다.

2.5 $s = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,32);
1.9 $s = base64_encode(openssl_random_pseudo_bytes(24));
1.68 $s = bin2hex(openssl_random_pseudo_bytes(16));
0.63 $s = base64_encode(random_bytes(24));
0.62 $s = bin2hex(random_bytes(16));
0.37 $s = substr(md5(rand()), 0, 32);
0.37 $s = substr(md5(mt_rand()), 0, 32);

실제로 얼마나 오래했는지는 중요하지 않지만 어느 것이 더 느리고 어느 것이 더 빠르므로 암호화 준비 등을 포함한 요구 사항에 따라 선택할 수 있습니다.

32 기호보다 짧은 문자열이 필요한 경우 정확성을 위해 MD5 주변의 substr ()이 추가되었습니다.

답을 위해 : 문자열이 연결되지 않았지만 덮어 쓰여지고 함수의 결과가 저장되지 않았습니다.


최선의 대답이라고 생각합니다. 감사!
NSukonny

10

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


주어진 길이의 문자열을 생성하지 않습니다
Timberman

@ Timberman은 이제 정확한 길이를 생성합니다.
Madan Sapkota

9

매우 빠른 방법 중 하나는 다음과 같은 작업을 수행하는 것입니다.

substr(md5(rand()),0,10);

그러면 길이가 10자인 임의의 문자열이 생성됩니다. 물론 일부는 계산 측면에서 조금 더 무겁다 고 말할 수도 있지만 요즘 프로세서는 md5 또는 sha256 알고리즘을 매우 빠르게 실행하도록 최적화되어 있습니다. 물론 rand()함수가 동일한 값을 반환하면 결과는 같을 것입니다. 보안이 문제라면 다음으로 변경하십시오 rand().mt_rand()


7
function rndStr($len = 64) {
     $randomData = file_get_contents('/dev/urandom', false, null, 0, $len) . uniqid(mt_rand(), true);
     $str = substr(str_replace(array('/','=','+'),'', base64_encode($randomData)),0,$len);
    return $str;
}

4
이것은 휴대용이 아닙니다. poix 이외의 환경에서 실행하려고하면 치명적인 오류가 발생합니다.
Bryan Agee


6

Laravel 5 프레임 워크의 도우미 기능

/**
 * Generate a "random" alpha-numeric string.
 *
 * Should not be considered sufficient for cryptography, etc.
 *
 * @param  int  $length
 * @return string
 */
function str_random($length = 16)
{
    $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}

4
"암호화 등에 충분하지 않은 것으로 간주되어야합니다." 이것은 강하게 강조되어야합니다.
Scott Arciszewski 2016 년


4

함수의 편집 된 버전은 정상적으로 작동하지만 발견 한 문제는 다음과 같습니다. 잘못된 문자를 사용하여 $ 문자를 묶었으므로 '문자는 때때로 생성 된 임의 문자열의 일부입니다.

이 문제를 해결하려면 다음을 변경하십시오.

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

에:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

이 방법으로 동봉 된 문자 만 사용되며 '문자는 생성 된 임의 문자열의 일부가되지 않습니다.


4

문자와 숫자가 포함 된 10 자의 임의 문자열을 생성하는 또 하나의 라이너. 그것은 배열을 생성합니다 range(크기를 설정하는 두 번째 매개 변수를 조정),이 배열 및 양수인 임의의 ASCII 문자 (범위 0-9 또는 AZ)를 통해 루프는 다음 문자열을 얻을 수있는 배열을 내파.

$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));

참고 : 이것은 PHP 5.3 이상에서만 작동합니다


마지막으로 32 비트 임의의 정수 나 셔플 된 문자열의 부풀린 해시가 아닌 진정한 무작위 솔루션 ...
Surrican

하나의 문제가 있습니다 : 숫자는 문자만큼 발생할 가능성이 높습니다. 이 페이지에서 최상의 솔루션을 얻으려면 +1하십시오. 그것을 완벽하게 조정하십시오.
Surrican

비틀기 ... 이렇게? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth

4

짧막 한 농담.

독창성이있는 거대한 현에는 빠릅니다.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}

md5(rand())난수를 생성하는 끔찍한 안전하지 않은 방법입니다.
Scott Arciszewski 2016 년

1
X 길이와 고유성이있는 문자열이 의도입니다. 진정한 무작위성은 의도가 아닙니다.
Jacob Smith


3

openssl_random_pseudo_bytes를 사용한 마지막 주석이 마음에 들었지만 원치 않는 문자를 제거해야했기 때문에 해결책이 아니 었으며 길이가 설정된 문자열을 얻을 수 없었습니다. 여기 내 해결책이 있습니다 ...

function rndStr($len = 20) {
    $rnd='';
    for($i=0;$i<$len;$i++) {
        do {
            $byte = openssl_random_pseudo_bytes(1);
            $asc = chr(base_convert(substr(bin2hex($byte),0,2),16,10));
        } while(!ctype_alnum($asc));
        $rnd .= $asc;
    }
    return $rnd;
}

3
function randomString($length = 5) {
    return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}

3

다음은 "1"및 "l", "O"및 "0"과 같은 문자를 제외하고 사용하기 쉬운 임의의 암호를 생성하는 간단한 한 줄 솔루션입니다. 여기서는 5 자이지만 쉽게 할 수 있습니다. 물론 변경하십시오.

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);

이것은 나중에 jquery에서 호출 할 임의의 ID 문자열을 만드는 데 적합합니다. IDK의 모범 사례이지만 이것이 허용 된 답변과
같은를

3

다른 해결책이 있습니다.

function genRandomString($length = 10)
{
    if($length < 1)
        $length = 1;
    return substr(preg_replace("/[^A-Za-z0-9]/", '', base64_encode(openssl_random_pseudo_bytes($length * 2))), 0, $length);
}

추신. 우분투에서 PHP 7.2를 사용하고 있습니다.


2

PHP 에서 임의의 문자열을 생성하는 다른 방법 은 다음과 같습니다.

function RandomString($length) {
    $original_string = array_merge(range(0,9), range('a','z'), range('A', 'Z'));
    $original_string = implode("", $original_string);
    return substr(str_shuffle($original_string), 0, $length);
}
echo RandomString(6);

2

다음은 진정한 고유 임의 키를 얻는 방법입니다.

$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;

time ()은 Unix 타임 스탬프이므로 위에서 언급 한 다른 임의의 요소와 비교하여 항상 고유하므로 time ()을 사용할 수 있습니다. 그런 다음 md5sum을 생성하고 생성 된 MD5 문자열 에서 원하는 길이를 취할 수 있습니다 . 이 경우 10자를 사용하고 더 고유하게 만들려면 더 긴 문자열을 사용할 수 있습니다.

이게 도움이 되길 바란다.


2
물론 time()고유하지는 않습니다. 현재 초가 끝날 때까지 동일한 값을 반복해서 반환합니다. 여기서 임의의 임의성을 제공하는 str_shuffle()것은 코드의 나머지 부분은 문자를 선택하는 샘플 만 줄입니다.
Álvaro González

1
그래서 기본적으로하는 일은 32 비트 정수를 섞는 것입니다. 엔트로피가 많지 않습니다 ...
Surrican

2
공격자는 반환 된 값 time()(타임 스탬프 일 뿐임)을 추측 할 수 있으며 이는 임의의 약한 소스입니다.
AL

2

PHP 5.1.0 부터 작동하는 PHP 기본 함수 만 사용하여 매개 변수화 된 하나의 라이너

str_shuffle(implode('', (array_intersect_key(($map =  array_map('chr', array_merge(array_map('mt_rand', array_fill(0, $length = 25, 48), array_fill(0,$length,57)),array_map('mt_rand', array_fill(0, $length, 65), array_fill(0,$length,90)),array_map('mt_rand', array_fill(0, $length, 97), array_fill(0,$length,122))))), array_flip($keys = array_rand($map, $length))))))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.