복붙노트

PHP : 임의의 고유 한 영숫자 문자열을 생성하는 방법은 무엇입니까?

PHP

PHP : 임의의 고유 한 영숫자 문자열을 생성하는 방법은 무엇입니까?

확인 링크에서 숫자와 문자를 사용하여 임의의 고유 한 문자열을 생성하는 것이 어떻게 가능합니까? 웹 사이트에 계정을 만들고 링크가있는 이메일을 보내는 경우처럼 계정을 확인하려면 해당 링크를 클릭해야합니다. 예 ... 그 중 하나.

PHP를 사용하여 그 중 하나를 생성하려면 어떻게해야합니까?

업데이트 : uniqid ()에 대해 기억하고 있습니다. 현재 시간 (마이크로 초)을 기반으로 고유 한 식별자를 생성하는 PHP 함수입니다. 나는 그것을 사용할 것이라고 생각한다.

해결법

  1. ==============================

    1.

    시간이 지남에 따라 절대적으로 고유 할 필요가없는 경우 :

    md5 (uniqid (rand (), true))

    그렇지 않은 경우 (사용자의 고유 로그인을 이미 결정한 경우) :

    md5(uniqid($your_user_login, true))
    
  2. ==============================

    2.

    이 문제를 해결하는 방법을 모색하고 있었지만 암호 검색에도 사용할 수있는 토큰을 만드는 기능이 필요합니다. 즉, 추측 할 수있는 토큰의 능력을 제한해야합니다. uniqid는 시간을 기반으로하므로 php.net에 따르면 "반환 값은 microtime ()"과 약간 다릅니다. uniqid는 기준을 충족하지 않습니다. PHP는 openssl_random_pseudo_bytes ()를 대신 사용하여 암호 학적으로 안전한 토큰을 생성 할 것을 권장합니다.

    빠르고 간단하고 핵심 답변은 다음과 같습니다.

    bin2hex(openssl_random_pseudo_bytes($bytes))
    

    length = $ bytes * 2의 임의의 영숫자 문자열을 생성합니다. 불행히도 이것은 [a-f] [0-9]의 알파벳 만 가지고 있지만 작동합니다. 아래는 내가 기준을 만족시킬 수있는 가장 강력한 기능입니다 (이것은 구현 된 Erik의 대답입니다).

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

    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

    EDIT (PHP7) : PHP7이 출시되면 표준 라이브러리는 위의 crypto_rand_secure 함수를 대체 / 개선 / 단순화 할 수있는 두 가지 새로운 기능을 갖게되었습니다. random_bytes ($ 길이) 및 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); // edited
    
        for ($i=0; $i < $length; $i++) {
            $token .= $codeAlphabet[random_int(0, $max-1)];
        }
    
        return $token;
    }
    
  3. ==============================

    3.

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

    필요한 경우 맞춤 알파벳을 사용할 수 있습니다. 지원되는 문자가있는 문자열을 생성자 또는 설정자에게 전달하십시오.

    <?php
    
    $customAlphabet = '0123456789ABCDEF';
    
    // Set initial alphabet.
    $generator = new RandomStringGenerator($customAlphabet);
    
    // Change alphabet whenever needed.
    $generator->setAlphabet($customAlphabet);
    
    SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
    q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
    I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
    AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
    duoRF6gAawNOEQRICnOUNYmStWmOpEgS
    sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
    eVywMdYXczuZmHaJ50nIVQjOidEVkVna
    baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
    iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
    OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa
    

    누군가가 도움이되기를 바랍니다. 건배!

  4. ==============================

    4.

    이 함수는 숫자와 문자를 사용하여 임의의 키를 생성합니다 :

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

    예제 출력 :

    zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8
    
  5. ==============================

    5.

    UUID (Universally Unique Identifier)를 사용할 수 있으며 사용자 인증 문자열에서 지불 트랜잭션 ID까지 어떤 용도로든 사용할 수 있습니다.

    UUID는 16 옥텟 (128 비트) 번호입니다. 정식 양식에서 UUID는 하이픈으로 구분 된 5 개의 그룹으로 표시되는 32 개의 16 진수로 표현되며 8-4-4-4-12 형식으로 총 36 자 (32 자의 영숫자 문자와 4 개의 하이픈)로 표시됩니다.

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

    // 함수 호출

    $transationID = generate_uuid();
    

    몇 가지 예제 출력은 다음과 같습니다.

    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
    

    미래에 도움이되기를 바랍니다 :)

  6. ==============================

    6.

    나는 늦었지만 Scott의 답변에서 제공하는 기능을 기반으로 한 좋은 연구 데이터가 있습니다. 그래서 나는이 5 일의 자동화 된 테스트를 위해 Digital Ocean 방울을 설정하고 생성 된 고유 한 문자열을 MySQL 데이터베이스에 저장했습니다.

    이 테스트 기간 동안 5 개의 다른 길이 (5, 10, 15, 20, 50)를 사용했고 각 길이에 대해 +/- 5 백만 개의 레코드가 삽입되었습니다. 테스트 기간 동안, 길이 5만이 0.5 백만 개 중 +/- 3K 중복을 생성했으며 나머지 길이는 중복을 생성하지 않았습니다. 따라서 Scott의 함수로 15 이상의 길이를 사용하면 신뢰할 수있는 고유 한 문자열을 생성 할 수 있다고 말할 수 있습니다. 내 연구 데이터를 보여주는 표는 다음과 같습니다.

    이게 도움이 되길 바란다.

  7. ==============================

    7.

    나는이 한 - 라이너를 사용합니다 :

    base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));
    

    여기서 length는 원하는 문자열의 길이 (4로 나눌 수 있습니다. 그렇지 않으면 4로 나눌 수있는 가장 가까운 수로 내림됩니다)

  8. ==============================

    8.

    예 : (의사 코드에서)

    int myInt = random(0, numcharacters)
    char[] codealphabet = 'ABCDEF12345'
    char random = codealphabet[i]
    repeat until long enough
    
  9. ==============================

    9.

    아래 코드를 사용하여 11 자의 난수를 생성하거나 요구 사항에 따라 숫자를 변경하십시오.

    $randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);
    
    or we can use custom function to generate the random number
    
     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);
    
  10. ==============================

    10.

    여기 당신을위한 최고의 고유 ID 생성기입니다. 나에 의해 만들어.

    <?php
    $d=date ("d");
    $m=date ("m");
    $y=date ("Y");
    $t=time();
    $dmt=$d+$m+$y+$t;    
    $ran= rand(0,10000000);
    $dmtran= $dmt+$ran;
    $un=  uniqid();
    $dmtun = $dmt.$un;
    $mdun = md5($dmtran.$un);
    $sort=substr($mdun, 16); // if you want sort length code.
    
    echo $mdun;
    ?>
    

    당신은 당신이 원하는대로 당신의 아이디에 대해 'var'을 에코 할 수 있습니다. 하지만 $ mdun이 더 낫다면 md5를 sha1로 바꿀 수 있지만 더 좋은 코드는 될 수 있습니다.

    고맙습니다.

  11. ==============================

    11.

    여기 내가 사용하는 것입니다 :

    md5(time() . rand());    
    // Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b
    
  12. ==============================

    12.

    확인 링크를 처리 할 때 해시 키를 사용하고 싶습니다. 마이크로 시간과 해시를 사용하는 것이 MD5를 사용하는 것이 좋습니다. 이유는 키가 마이크로 시간을 기준으로 해시되므로 키가 동일해야하는 이유가 없어야하기 때문입니다.

  13. ==============================

    13.

    function random_string($length = 8) {
        $alphabets = range('A','Z');
        $numbers = range('0','9');
        $additional_characters = array('_','=');
        $final_array = array_merge($alphabets,$numbers,$additional_characters);
           while($length--) {
          $key = array_rand($final_array);
    
          $password .= $final_array[$key];
                            }
      if (preg_match('/[A-Za-z0-9]/', $password))
        {
         return $password;
        }else{
        return  random_string();
        }
    
     }
    
  14. ==============================

    14.

    Scott, 네, 당신은 매우 잘 쓰고 좋은 해결책입니다! 감사.

    또한 각 사용자마다 고유 한 API 토큰을 생성해야합니다. 다음은 내 접근 방식입니다, 나는 사용자 정보 (사용자 ID와 사용자 이름)를 사용했습니다 :

    public function generateUniqueToken($userid, $username){
    
            $rand = mt_rand(100,999);
        $md5 = md5($userid.'!(&^ 532567_465 ///'.$username);
    
        $md53 = substr($md5,0,3);
        $md5_remaining = substr($md5,3);
    
        $md5 = $md53. $rand. $userid. $md5_remaining;
    
        return $md5;
    }
    

    내가 할 수있는 개선이 있는지 한번 살펴보고 알려주십시오. 감사

  15. ==============================

    15.

    이전 예제를 읽은 후에 나는 이것을 생각해 냈습니다.

    protected static $nonce_length = 32;
    
    public static function getNonce()
    {
        $chars = array();
        for ($i = 0; $i < 10; $i++)
            $chars = array_merge($chars, range(0, 9), range('A', 'Z'));
        shuffle($chars);
        $start = mt_rand(0, count($chars) - self::$nonce_length);
        return substr(join('', $chars), $start, self::$nonce_length);
    }
    

    나는 배열 [0-9, A-Z]의 10 배를 복사하고, substr ()의 무작위 시작점을 얻은 후에 요소를 섞는다. [a-z]와 다른 요소를 배열에 추가 할 수 있습니다. 더 많거나 적게 복제하거나, 나보다 창조적 일 수 있습니다.

  16. ==============================

    16.

    나는 이것이 가장 좋은 방법이라고 생각한다.

    str_shuffle(md5(rand(0,100000)))
    
  17. ==============================

    17.

    <?php
    function generateRandomString($length = 11) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    
    }
    
    ?>
    

    위의 함수는 길이가 11자인 임의의 문자열을 생성합니다.

  18. ==============================

    18.

    이 두 줄의 코드를 사용하여 고유 한 문자열을 생성하고 약 10000000 번 반복 테스트했습니다.

      $sffledStr= str_shuffle('abscdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+');
        $uniqueString = md5(time().$sffledStr);
    
  19. ==============================

    19.

    정말 임의의 문자열의 경우

    <?php
    
    echo md5(microtime(true).mt_Rand());
    

    출력 :

    40a29479ec808ad4bcff288a48a25d5c
    

    그래서 정확히 같은 시간에 여러 번 문자열을 생성하려고해도 다른 결과가 나옵니다.

  20. ==============================

    20.

    이 함수는 문자와 숫자 (영숫자)가 포함 된 임의의 문자열을 생성 할 수있는 간단한 함수입니다. 문자열 길이를 제한 할 수도 있습니다. 이러한 임의의 문자열은 추천 코드, 프로모션 코드, 쿠폰 코드 등 다양한 용도로 사용할 수 있습니다. 함수는 다음 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
    */
    
  21. ==============================

    21.

    나는 기존의 모든 아이디어에 대한 문제는 아마도 그것들이 유일 할 것이지만 확실히 독특하다고 (Dariusz Walczak의 loletech에 대한 답변에서 지적한 바와 같이) 믿는다. 실제로 고유 한 솔루션이 있습니다. 스크립트에 일종의 메모리가 필요합니다. 나에게 이것은 SQL 데이터베이스이다. 어딘가에 파일을 쓸 수도 있습니다. 두 가지 구현이 있습니다.

    첫 번째 방법 : 고유성을 제공하는 1보다는 2 개의 필드가 있어야합니다. 첫 번째 필드는 임의가 아니지만 고유 한 ID 번호입니다 (첫 번째 ID는 1, 두 번째 ID는 2 ...). SQL을 사용하는 경우, AUTO_INCREMENT 특성을 사용하여 ID 필드를 정의하십시오. 두 번째 필드는 고유하지 않지만 임의적입니다. 사람들이 이미 언급 한 다른 기술로 생성 할 수 있습니다. 스콧의 아이디어는 좋았지 만, md5는 편리하고 아마도 대부분의 목적에 충분할 것입니다 :

    $random_token = md5($_SERVER['HTTP_USER_AGENT'] . time());
    

    두 번째 방법 : 기본적으로 같은 아이디어이지만 처음에는 생성 될 문자열의 최대 개수를 선택합니다. 이것은 1 조와 같이 아주 큰 숫자 일 수 있습니다. 그런 다음 동일한 작업을 수행하고 ID를 생성하지만 모든 ID가 동일한 자릿수가되도록 입력하십시오. 그런 다음 ID를 임의의 문자열과 연결하십시오. 그것은 대부분의 목적을 위해 충분히 무작위 일 것이나, ID 단면도는 또한 유일하다는 것을 보증 할 것이다.

  22. ==============================

    22.

    여기 내가 내 프로젝트 중 하나에서 사용하고있는 것은 훌륭하게 작동하고 있으며, 독창적 인 랜덤을 생성합니다. TOKEN :

    $timestampz=time();
    
    function generateRandomString($length = 60) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }
    
    
    $tokenparta = generateRandomString();
    
    
    $token = $timestampz*3 . $tokenparta;
    
    echo $token;
    

    사용자가이 토큰이 어떻게 생성되는지 궁금해 할 수도있는 사용자를 위해 혼란을주기 위해 타임 스탬프에 3을 곱한 점에 유의하십시오.

    나는 그것이 도움이되기를 바랍니다 :)

  23. ==============================

    23.

    이 코드를 사용할 수 있습니다. 나는 그것이 당신에게 도움이되기를 바랍니다.

    function rand_code($len)
    {
     $min_lenght= 0;
     $max_lenght = 100;
     $bigL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     $smallL = "abcdefghijklmnopqrstuvwxyz";
     $number = "0123456789";
     $bigB = str_shuffle($bigL);
     $smallS = str_shuffle($smallL);
     $numberS = str_shuffle($number);
     $subA = substr($bigB,0,5);
     $subB = substr($bigB,6,5);
     $subC = substr($bigB,10,5);
     $subD = substr($smallS,0,5);
     $subE = substr($smallS,6,5);
     $subF = substr($smallS,10,5);
     $subG = substr($numberS,0,5);
     $subH = substr($numberS,6,5);
     $subI = substr($numberS,10,5);
     $RandCode1 = str_shuffle($subA.$subD.$subB.$subF.$subC.$subE);
     $RandCode2 = str_shuffle($RandCode1);
     $RandCode = $RandCode1.$RandCode2;
     if ($len>$min_lenght && $len<$max_lenght)
     {
     $CodeEX = substr($RandCode,0,$len);
     }
     else
     {
     $CodeEX = $RandCode;
     }
     return $CodeEX;
    }
    

    PHP의 임의 코드 생성기에 대한 세부 정보

  24. ==============================

    24.

    심하게 감속하고있는 불필요한 루프를 제거하여 위의 Scotts 코드를 단순화하고 openssl_random_pseudo_bytes를 한 번만 호출하는 것보다 안전하지 않게합니다.

    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
     $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
     return $min + $rnd%$range;
    }
    
    function getToken($length)
    {
     return bin2hex(openssl_random_pseudo_bytes($length)
    }
    
  25. from https://stackoverflow.com/questions/1846202/php-how-to-generate-a-random-unique-alphanumeric-string by cc-by-sa and MIT lisence