PHP: Cara membuat random, unik, string alfanumerik?

Bagaimana itu akan mungkin untuk menghasilkan acak, unik string menggunakan angka dan huruf untuk digunakan dalam memverifikasi link? Seperti ketika anda membuat akun di situs web, dan mengirimkan email dengan link, dan anda harus klik link tersebut untuk memverifikasi akun anda...yeah...salah satu dari mereka.

Bagaimana saya dapat menghasilkan salah satu dari orang-orang yang menggunakan PHP?

Update: Hanya ingat tentang uniqid(). It's sebuah fungsi PHP yang menghasilkan sebuah pengenal unik berdasarkan waktu saat ini di mikrodetik. Saya pikir saya'll gunakan itu.

Mengomentari pertanyaan (3)

Aku hanya melihat ke dalam bagaimana untuk memecahkan masalah yang sama, tapi saya juga ingin fungsi saya untuk membuat sebuah token yang dapat digunakan untuk pengambilan password juga. Ini berarti bahwa saya perlu untuk membatasi kemampuan token untuk ditebak. Karena uniqid didasarkan pada waktu, dan sesuai dengan php.net "nilai kembali adalah sedikit berbeda dari microtime()", uniqid tidak memenuhi kriteria. PHP merekomendasikan menggunakan openssl_random_pseudo_bytes() bukan untuk menghasilkan cryptographically aman token.

Cepat, singkat dan to the point jawabannya adalah:

bin2hex(openssl_random_pseudo_bytes($bytes))

yang akan menghasilkan string acak dari karakter alfanumerik panjang = $byte * 2. Sayangnya ini hanya memiliki alfabet [a-f][0-9], tapi itu bekerja.


Di bawah ini adalah fungsi terkuat saya bisa membuat yang memenuhi kriteria (Ini adalah aplikasi yang diimplementasikan versi Erik's jawaban).
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  $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) bekerja sebagai drop-in pengganti rand() atau mt_rand. Menggunakan openssl_random_pseudo_bytes untuk membantu membuat nomor acak antara $min, $max.

method gettoken($panjang) menciptakan alfabet untuk digunakan dalam token dan kemudian menciptakan sebuah string panjang $panjang.

EDIT: saya lupa mengutip sumber - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322

EDIT (PHP7): Dengan rilis PHP7, perpustakaan standar sekarang memiliki dua fungsi baru yang dapat mengganti/memperbaiki/menyederhanakan crypto_rand_secure fungsi di atas. random_bytes($panjang) dan random_int($min, $max)

http://php.net/manual/en/function.random-bytes.php

http://php.net/manual/en/function.random-int.php

Contoh:

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;
}
Komentar (31)
Larutan

KeamananPemberitahuan**: solusi Ini tidak boleh digunakan dalam situasi di mana kualitas anda keacakan dapat mempengaruhi keamanan dari sebuah aplikasi. Secara khusus, rand() dan uniqid() adalah tidak cryptographically secure random number generator. Lihat Scott's jawaban untuk alternatif yang aman.

Jika anda tidak perlu untuk menjadi benar-benar unik dari waktu ke waktu:

md5(uniqid(rand(), true))

Jika tidak (mengingat anda telah ditentukan login yang unik untuk anda pengguna):

md5(uniqid($your_user_login, true))
Komentar (6)

Berorientasi objek versi paling up-memilih solusi

I've dibuat berorientasi objek solusi berdasarkan Scott's jawaban:

<?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 = $range);

        return ($min + $rnd);
    }
}

Penggunaan

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

Custom alfabet

Anda dapat menggunakan kustom alfabet jika diperlukan. Hanya lulus string dengan didukung karakter untuk konstruktor atau setter:

<?php

$customAlphabet = '0123456789ABCDEF';

// Set initial alphabet.
$generator = new RandomStringGenerator($customAlphabet);

// Change alphabet whenever needed.
$generator->setAlphabet($customAlphabet);

Berikut ini's output sampel

SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa

Saya berharap ini akan membantu seseorang. Cheers!

Komentar (5)

I'm terlambat tapi aku'm di sini dengan beberapa data penelitian didasarkan pada fungsi-fungsi yang disediakan oleh Scott's jawaban. Jadi saya set up Digital Ocean droplet hanya untuk 5 hari selama tes otomatis dan disimpan unik yang dihasilkan string dalam database MySQL.

Selama periode pengujian, saya menggunakan 5 panjang yang berbeda (5, 10, 15, 20, 50) dan +/-0.5 juta catatan yang dimasukkan untuk setiap panjang. Selama saya tes, hanya panjang 5 yang dihasilkan +/-3K duplikat dari 0,5 juta dan sisanya panjang didn't menghasilkan duplikat. Jadi kita dapat mengatakan bahwa jika kita menggunakan panjang 15 atau di atas dengan Scott's fungsi, maka kita dapat menghasilkan yang sangat handal unik string. Berikut ini adalah tabel yang menunjukkan data penelitian saya:

Update: Aku dibuat sederhana Heroku aplikasi menggunakan fungsi-fungsi yang mengembalikan token sebagai respon JSON. Aplikasi dapat diakses di https://uniquestrings.herokuapp.com/api/token?length=15

Saya harap ini membantu.

Komentar (0)

Fungsi ini akan menghasilkan kunci acak yang menggunakan angka dan huruf:

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

Contoh output:

zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8
Komentar (2)

Anda dapat menggunakan UUID(Universal Unique Identifier), dapat digunakan untuk tujuan apapun, dari otentikasi pengguna string untuk transaksi pembayaran id.

UUID ini 16 oktet (128-bit) nomor. Dalam bentuk kanonik, UUID diwakili oleh 32 digit heksadesimal, ditampilkan dalam lima kelompok yang dipisahkan oleh tanda hubung, dalam bentuk 8-4-4-4-12 untuk total 36 karakter (32 karakter alfanumerik dan empat tanda hubung).

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

}

//memanggil funtion

$transationID = generate_uuid();

beberapa contoh output akan menjadi seperti:

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

berharap itu membantu seseorang di masa depan :)

Komentar (1)

Saya menggunakan ini satu-liner:

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

dimana suhu udara lebih panjang dari string yang diinginkan (dibagi 4, jika tidak maka akan dibulatkan ke angka terdekat habis dibagi 4)

Komentar (2)

Gunakan kode berikut untuk menghasilkan nomor acak dari 11 karakter atau mengubah jumlah sesuai kebutuhan anda.

$randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);

atau kita dapat menggunakan fungsi kustom untuk menghasilkan nomor acak

 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);
Komentar (2)
  1. Menghasilkan nomor acak menggunakan favorit acak-nomor generator
  2. Mengalikan dan membagi itu untuk mendapatkan jumlah yang sesuai dengan jumlah karakter dalam kode anda alfabet
  3. Dapatkan item pada indeks di kode alfabet.
  4. Ulangi dari 1) sampai anda memiliki panjang anda ingin

e.g (dalam pseudo code)

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

Berikut ini adalah ultimate unik id generator untuk anda. dibuat oleh saya.

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

anda dapat echo setiap 'var' id anda seperti yang anda suka. tapi $mdun lebih baik, anda dapat mengganti md5, sha1 untuk untuk kode yang lebih baik tapi itu akan menjadi sangat panjang yang mungkin anda tidak perlu.

Terima kasih.

Komentar (2)

Ketika mencoba untuk menghasilkan password acak yang anda mencoba untuk :

  • Pertama menghasilkan cryptographically secure set random byte

  • Kedua adalah mengubah orang-orang random byte ke string cetak

Sekarang, ada beberapa cara untuk menghasilkan byte random di php seperti :

$length = 32;

//PHP 7+
$bytes= random_bytes($length);

//PHP < 7
$bytes= openssl_random_pseudo_bytes($length);

Kemudian anda ingin mengubah ini random byte ke string cetak :

Anda dapat menggunakan bin2hex :

$string = bin2hex($bytes);

atau base64_encode :

$string = base64_encode($bytes);

Namun, perhatikan bahwa anda tidak mengontrol panjang string jika anda menggunakan base64. Anda dapat menggunakan bin2hex untuk melakukan itu, menggunakan 32 byte akan berubah menjadi 64 char string. Tapi itu hanya akan bekerja seperti di BAHKAN string.

Jadi pada dasarnya anda hanya dapat melakukan :

$length = 32;

if(PHP_VERSION>=7){
    $bytes= random_bytes($length);
}else{
    $bytes= openssl_random_pseudo_bytes($length);
} 

$string = bin2hex($bytes);
Komentar (0)

Berikut adalah apa yang saya gunakan:

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

Untuk benar-benar random string, anda dapat menggunakan

<?php

echo md5(microtime(true).mt_Rand());

output :

40a29479ec808ad4bcff288a48a25d5c

jadi bahkan jika anda mencoba untuk menghasilkan string beberapa kali di waktu yang bersamaan, anda akan mendapatkan output yang berbeda.

Komentar (0)
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();
    }

 }
Komentar (0)

Saya ingin menggunakan hash kunci ketika berhadapan verifikasi link. Saya akan merekomendasikan menggunakan microtime dan hashing menggunakan MD5 karena seharusnya tidak ada alasan mengapa kunci harus sama karena hash berdasarkan microtime.

  1. $key = md5(rand());
  2. $key = md5(microtime());
Komentar (0)

Jika anda ingin menghasilkan sebuah string unik di PHP, coba berikut ini.

md5(uniqid().mt_rand());

Dalam hal ini,

uniqid() - Itu akan menghasilkan string unik. Fungsi ini mengembalikan timestamp berdasarkan pengenal unik sebagai string.

mt_rand() - Menghasilkan nomor acak.

md5() - akan menghasilkan hash string.

Komentar (0)

setelah membaca contoh-contoh sebelumnya saya datang dengan ini:

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

Saya gandakan 10 kali array[0-9,A-Z] dan mengocok elemen, setelah saya mendapatkan titik awal acak untuk substr() untuk lebih 'kreatif' :) anda dapat menambahkan [a-z] dan unsur-unsur lain untuk array, duplikat lebih atau kurang, lebih kreatif dari saya

Komentar (0)

Ini adalah sebuah fungsi sederhana yang memungkinkan anda untuk menghasilkan string acak yang mengandung Huruf dan Angka (alphanumeric). Anda juga dapat membatasi panjang string. Ini random string dapat digunakan untuk berbagai tujuan, termasuk: Kode Referral, Kode Promosi, Kode Kupon. Fungsi bergantung pada berikut fungsi 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
*/
Komentar (0)

Berikut adalah apa yang saya'm menggunakan salah satu dari proyek-proyek saya, it's bekerja dan menghasilkan UNIK RANDOM 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;

Harap dicatat bahwa saya dikalikan timestamp oleh tiga untuk menciptakan kebingungan bagi siapapun pengguna mungkin bertanya-tanya bagaimana token ini dihasilkan ;)

Saya berharap hal ini membantu :)

Komentar (2)

Saya pikir ini adalah metode terbaik untuk digunakan.

str_shuffle(md5(rand(0,100000)))
Komentar (0)