development

PHP 임의 문자열 생성기

big-blog 2020. 9. 29. 08:04
반응형

PHP 임의 문자열 생성기


PHP에서 임의의 문자열을 만들려고하는데 다음과 같이 출력이 전혀 발생하지 않습니다.

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

    RandomString();
    echo $randstring;

내가 도대체 ​​뭘 잘못하고있는 겁니까?


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

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

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


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

한 가지 더.

UPDATED (이제 임의 길이의 문자열 생성) :

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

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

그게 다야. :)


이 질문에 대한 답변은 많지만 CSPRNG ( Cryptographically Secure Pseudo-Random Number Generator )를 활용하는 것은 없습니다 .

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

자신 만의 솔루션을 고집하는 분들을 위해 PHP 7.0.0이 random_int()이러한 목적 을 제공 합니다. 아직 PHP 5.x 를 사용 중이라면random_int() PHP 7로 업그레이드하기 전에 새 API를 사용할 수 있도록 PHP 5 폴리 필을 작성했습니다 .

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 필요)


이렇게하면 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

@tasmaniski : 귀하의 답변이 저에게 효과적이었습니다. 나는 똑같은 문제가 있었고, 같은 답을 찾고있는 사람들에게 그것을 제안 할 것입니다. 여기 @tasmaniski에서 온 것입니다.

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

다음은 난수를 만드는 방법을 보여주는 YouTube 동영상입니다.


응용 프로그램에 따라 (비밀번호를 생성하고 싶음) 다음을 사용할 수 있습니다.

$string = base64_encode(openssl_random_pseudo_bytes(30));

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

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


다음은 스크립트 수준 루핑이나 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);

이 메서드는 문자 목록을 무작위로 반복 한 다음 결합 된 문자열을 섞고 지정된 문자 수를 반환합니다.

반환 된 문자열의 길이를 임의 화하여 (8 ~ 15 자 사이의 임의 문자열)로 대체 $chrRandomLength하여 이를 추가로 임의화할 수 있습니다 mt_rand(8, 15).


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

타다!


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

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_rand이상에 따라 랜덤 그리고 PHP의 7에서 rand함수의 별칭 mt_rand.


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

$randstring = RandomString();
echo $randstring;

또는 반환 값을 직접 에코합니다.

echo RandomString();

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

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

먼저 사용할 알파벳을 정의합니다.

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

짧은 방법 ..

다음은 임의의 문자열을 생성하는 가장 짧은 방법입니다.

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

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

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

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

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 ()이 추가되었습니다.

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


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;
}

이것은 관리자 소스 에서 가져 왔습니다 .

/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
    return md5(uniqid(mt_rand(), true));
}

Adminer , PHP로 작성된 데이터베이스 관리 도구.


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

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

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


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

/**
 * @param int $length
 * @param string $abc
 * @return string
 */
function generateRandomString($length = 10, $abc = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
    return substr(str_shuffle($abc), 0, $length);
}

http://www.xeweb.net/2011/02/11/generate-a-random-string-az-0-9-in-php/의 출처


함수의 편집 된 버전은 잘 작동하지만 한 가지 문제가 있습니다. $ characters를 묶기 위해 잘못된 문자를 사용했기 때문에 '문자가 생성되는 임의 문자열의 일부가되는 경우가 있습니다.

이를 수정하려면 다음을 변경하십시오.

$characters = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

에:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

이렇게하면 괄호 안의 문자 만 사용되며 '문자는 생성되는 임의 문자열의 일부가되지 않습니다.


또 다른 한 줄로, 문자와 숫자가 포함 된 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 이상에서만 작동합니다.


짧막 한 농담.

약간의 독창성을 가진 거대한 현의 경우 빠릅니다.

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

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;
}

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

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

Parametrised one-liner using only PHP native functions, working since PHP 5.1.0

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

There is simple code:

echo implode("",array_map(create_function('$s','return substr($s,mt_rand(0,strlen($s)),1);'),array_fill(0,16,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")));

There is a simple guide:

  • To change the length of string, please change the 16 to another value, only.
  • To select from different characters, please change the character string.

Finally I have found a solution to get random and unique values.

My solution is:

substr(md5(time()), 0, 12)

time always return a timestamp, and it is always unique. You can use it with MD5 to make it better.


There are better alternatives to this. Many was already posted so I give you only your stuff back with fixes:

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

    RandomString();

    echo $randstring;
?>

Also you may be interested in:

<?php
    function RandomString()
    {
        global $randstring;
        $characters = str_split('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
           array_filter ($characters,function($var)use($characters,&$randstring){
                $randstring .= $characters[rand(0, count($characters)-1)];
        });
        return $randstring;
    }

    RandomString();
    echo $randstring.'<hr>';

    //.. OR  ..
    $randstring = '';
    echo(RandomString());
?>

Or another one:

<?php
    function s($length){
      for($i=0;
          ($i<$length) and
          (
              ($what=rand(1,3))

              and

              (
                  (
                      ($what==1) and
                      ($t=rand(48, 57)
                  )
                  ) or

                  (
                      ($what==2) and
                      ($t=rand(65, 90))
                  ) or

                  (
                      ($what==3) and
                      ($t=rand(97, 122)
                  )
                  )
              ) and
              (print chr($t))
          );

          $i++)

              ;
    }
    s(10);
?>

function getRandomString($length) {
  $salt = array_merge(range('a', 'z'), range(0, 9));
  $maxIndex = count($salt) - 1;

  $result = '';
  for ($i = 0; $i < $length; $i++) {
    $index = mt_rand(0, $maxIndex);
    $result .= $salt[$index];
  }
  return $result
}

Here is how I am doing it to get a true unique random key:

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

You can use time() since it is a Unix timestamp and is always unique compared to other random mentioned above. You can then generate the md5sum of that and take the desired length you need from the generated MD5 string. In this case I am using 10 characters, and I could use a longer string if I would want to make it more unique.

I hope this helps.

참고URL : https://stackoverflow.com/questions/4356289/php-random-string-generator

반응형