PHP pembuat string acak

814

Saya mencoba membuat string acak dalam PHP, dan saya sama sekali tidak mendapatkan output dengan ini:

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

    RandomString();
    echo $randstring;

Apa yang saya lakukan salah?

Kapten Lightning
sumber
241
Solusi satu baris saya untuk menghasilkan string pendek adalah substr (md5 (rand ()), 0, 7); semoga sukses ...
tasmaniski
5
@tasmaniski .. Solusi Anda baik-baik saja .. Tapi kurang acak! Dalam contoh Anda jumlah string acak yang dapat dihasilkan dibatasi oleh ukuran bilangan bulat. (2 ^ 32) di maks .. Dalam hal solusi lain, Anda dapat menghasilkan (62 ^ 8) .. Jika, saya ingin string lebih besar, maka jumlah string berbeda tetap di maks 2 ^ 32, tetapi dalam solusi lain meningkat menjadi (62 ^ n) ..
Manu
9
Anda lupa menambahkan setiap karakter baru yang dihasilkan ke string. Anda hanya menimpanya seperti apa adanya. Seharusnya $ randstring. = $ Karakter ..
Spock
3
@CaptainLightning Bisakah Anda menukar jawaban yang diterima dengan salah satu yang lebih aman? :)
Scott Arciszewski
2
strlen($characters)=> strlen($characters) - 1- panjang string dimulai dengan 1
Zippp

Jawaban:

1394

Untuk menjawab pertanyaan ini secara khusus, dua masalah:

  1. $randstring tidak ada dalam ruang lingkup saat Anda menggemakannya.
  2. Karakter tidak disatukan dalam satu lingkaran.

Berikut cuplikan kode dengan koreksi:

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

Keluarkan string acak dengan panggilan di bawah ini:

// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();

Harap dicatat bahwa ini menghasilkan string acak yang dapat diprediksi. Jika Anda ingin membuat token aman, lihat jawaban ini .

Stephen Watkins
sumber
34
@ FranciscoPresencia, Lebih baik "membuang" variabel tambahan pada memanggil metode dalam kondisi membandingkan loop.
Rico Sonntag
200
Semua itu berhasil, mengapa tidak seperti itu saja substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH
4
Terima kasih untuk kodenya, tapi tolong ubah rand()ke mt_rand(). Saya menggunakan metode Anda dan mengalami banyak tabrakan dengan nama.
Nate
5
@FranciscoPresencia apakah Anda tahu betapa tidak efisiennya hal itu? Anda memeriksa panjang string dua kali per iterasi! Strlen di dalam loop harus di-cache dalam variabel sebelum memasukkan loop juga.
developerbmw
4
Ini bukan solusi yang baik. String yang dihasilkan ini dapat diprediksi. :(
Scott Arciszewski
370

Catatan: str_shuffle()penggunaan internal rand(), yang tidak cocok untuk keperluan kriptografi (misalnya menghasilkan kata sandi acak). Anda menginginkan generator nomor acak yang aman sebagai gantinya. Itu juga tidak memungkinkan karakter untuk mengulang.

Satu lagi jalan.

DIPERBARUI (sekarang ini menghasilkan string apa pun):

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

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

Itu dia. :)

A. Cheshirov
sumber
64
+1 untuk jawaban terpendek :). Tapi bukan jawaban terbaik untuk setiap use-case. Kode ini akan menampilkan string di mana setiap karakter tidak akan muncul lebih dari satu kali (sehingga membuatnya lebih lemah untuk serangan brute force) dan tidak akan menghasilkan apa pun yang lebih dari 62 karakter.
David
17
Jangan lakukan ini, ini sangat lemah. Semakin lama Anda membuat string acak Anda, akan semakin lemah.
Abhi Beckert
23
Lemah mungkin, tetapi cepat dan mudah. Bergantung pada case-use, ini baik-baik saja - saya sudah menggunakannya karena saya tidak membutuhkan keamanan atau kekuatan; hanya shuffle cepat-api. Saya sedang menulis unit test, dan ini memberi saya input acak yang sesuai untuk diuji.
SDC
23
@FranciscoPresencia alasannya tidak aman adalah karena tidak pernah menggunakan karakter yang sama dua kali. Itu membuatnya menjadi penghasil kata sandi yang mengerikan . Tolong semua orang berhenti memilih ini, itu benar-benar tidak aman tidak boleh digunakan. Ketika kata sandi semakin panjang, jumlah karakter yang harus Anda uji dalam kekuatan kasar menjadi lebih pendek karena Anda tidak perlu repot menguji karakter yang sebelumnya digunakan.
Abhi Beckert
8
@FranciscoPresencia: Saya mendukung komentar Anda tentang menghindari penggunaan ini untuk kata sandi acak. Namun, saya tidak setuju bahwa jawaban ini tidak boleh ditambah satu. Saya telah plus-one'd opsi ini karena ini merupakan solusi satu-line yang efektif untuk menghasilkan string acak (topik asli dari pertanyaan ini).
bwright
331

Ada banyak jawaban untuk pertanyaan ini, tetapi tidak satupun dari mereka yang memanfaatkan Pseudo-Random Number Generator (CSPRNG) Cryptographically Secure .

Jawaban sederhana, aman, dan benar adalah dengan menggunakan RandomLib dan jangan menemukan kembali kemudi.

Bagi Anda yang bersikeras menciptakan solusi Anda sendiri, PHP 7.0.0 akan menyediakan random_int()untuk tujuan ini; jika Anda masih menggunakan PHP 5.x, kami menulis polyfill PHP 5 untukrandom_int() sehingga Anda dapat menggunakan API baru bahkan sebelum Anda meningkatkan ke PHP 7.

Menghasilkan bilangan bulat acak dengan aman di PHP bukanlah tugas yang sepele. Anda harus selalu berkonsultasi dengan pakar kriptografi StackExchange tempat tinggal Anda sebelum menerapkan algoritme buatan sendiri dalam produksi.

Dengan generator integer yang aman, menghasilkan string acak dengan CSPRNG adalah jalan-jalan di taman.

Membuat String yang Aman dan Acak

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

Penggunaan :

$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');
$c = random_str();

Demo : https://3v4l.org/IMJGF (Abaikan kegagalan PHP 5; perlu random_compat)

Scott Arciszewski
sumber
3
Pada awal fungsi tambahkan $keyspace = str_shuffle($keyspace );untuk keamanan yang lebih
Jevgenij Dmitrijev
13
Apa yang Anda maksud dengan "untuk keamanan lebih"? Kami sudah menggunakan generator nomor acak yang aman.
Scott Arciszewski
5
@ JGEstiot Menciptakan string acak yang aman membutuhkan keacakan yang aman secara kriptografis. Seseorang yang mencari "cara membuat string acak di PHP" lebih baik dilayani oleh jawaban yang aman daripada jawaban yang tidak aman.
Scott Arciszewski
1
@ Scott Arciszewski Anda tidak perlu membuat string acak kriptografis setiap kali Anda membuat string acak. Pertanyaannya adalah tentang membuat string acak dan ini tidak ada hubungannya dengan keamanan. Anda berasumsi bahwa string akan digunakan dalam konteks peka-keamanan dan Anda menambahkan lapisan kompleksitas yang menghalangi inti pertanyaan.
JG Estiot
45
Menggunakan random_int()alih-alih rand()atau mt_rand()tidak menambah kerumitan bagi pengembang. Pada saat yang sama, itu memberi mereka keamanan yang lebih besar. Orang-orang yang datang ke StackOverflow mencari solusi cepat mungkin tidak tahu apakah benda yang mereka bangun perlu aman atau tidak. Jika kami memberi mereka jawaban aman secara default, mereka menciptakan Internet yang lebih aman walaupun, dari sudut pandang mereka, itu benar-benar kebetulan. Mengapa Anda menentang tujuan ini adalah misteri bagi saya.
Scott Arciszewski
156

Ini menciptakan string heksadesimal sepanjang 20 karakter:

$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars

Dalam 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
Rudie
sumber
Harap dicatat bahwa openssl_random_pseudo_bytes()tidak menggunakan algoritma yang kuat secara kriptografis sampai php 5.6. Bug terkait: bugs.php.net/bug.php?id=70014
acidtv
Perhatikan juga bahwa string terkecil yang dapat dibuat adalah panjang 2. Jika Anda melewatkan panjang byte 1 atau kurang, openssl_random_pseudo_bytes()Anda tidak akan mendapatkan apa-apa. Juga, perhatikan bahwa ketika menggunakan bin2hex(openssl_random_pseudo_bytes($length / 2))karena Anda bekerja dengan bilangan bulat, itu akan secara otomatis menghapus modulo dan akan menggunakan kelipatan terendah berikutnya 2. Jadi, $length = 19akan menghasilkan string dengan panjang 18.
Nathan F.
Proposal untuk menggunakannya sebagai konten file yang dapat dibuka melalui fgets($fp, 1024)dan setiap editor file yang memiliki masalah dengan garis yang sangat panjang: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }Setel $splitke nulljika harus mengembalikan satu-baris. Dengan itu Anda dapat menggunakannya untuk kedua kasus.
mgutt
Saya sangat suka solusi random_bytes untuk PHP 7, tetapi jika Anda membutuhkan string untuk sejumlah karakter, apakah ini akan berfungsi? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programster
Ini benar-benar tanpa keraguan solusi terbaik. Memakan ruang yang sangat sedikit dan sangat mudah dimengerti.
Matthew Campbell
92

@tasmaniski: jawaban Anda berhasil untuk saya. Saya memiliki masalah yang sama, dan saya akan menyarankannya untuk mereka yang pernah mencari jawaban yang sama. Ini dia dari @tasmaniski:

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

Ini adalah video youtube yang menunjukkan kepada kita cara membuat angka acak

Humphrey
sumber
6
jika string Anda hanya didasarkan pada bilangan bulat acak, mengapa tidak menggunakan bilangan bulat acak saja? mereka tumpukan jerami tidak mendapatkan lebih dalam dengan hashing itu ... dan dengan memotong hash Anda benar-benar meremehkan entropi kecil Anda harus mulai dengan.
The Surrican
4
Perlu diingat md5akan menghasilkan batas 30 karakter dan selalu huruf kecil.
fyrye
3
Selain itu, rand () tidak boleh digunakan untuk kriptografi. Jika Anda ingin membuat string suara crypographically, gunakan openssl_random_pseudo_bytes .
mattkgross
md5(rand())hanya menawarkan 2 ^ 32 nilai yang memungkinkan. Ini berarti setelah, rata-rata, 2 ^ 16 string acak Anda akan mengharapkan satu untuk mengulangi.
Scott Arciszewski
2
Yah..saya bertaruh OP tidak berbicara tentang "string acak yang aman". Solusi ini ringkas, mudah dan cantik untuk diingat, untuk kasus penggunaan yang tepat . Dan, jika Anda perlu menjaga kemungkinan tabrakan, mengapa tidak menambahkan / menambahkan cap waktu ke string acak? :)
Erenor Paz
46

Bergantung pada aplikasi Anda (saya ingin menghasilkan kata sandi), Anda dapat menggunakannya

$string = base64_encode(openssl_random_pseudo_bytes(30));

Menjadi base64, mereka dapat berisi =atau -juga karakter yang diminta. Anda dapat membuat string yang lebih panjang, lalu filter dan potong untuk menghilangkannya.

openssl_random_pseudo_bytestampaknya menjadi cara yang disarankan untuk menghasilkan angka acak yang tepat di php. Kenapa randtidak pakai /dev/randomsaya tidak tahu.

rjmunro
sumber
2
rand tidak menggunakan / dev / urandom karena itu hanya tersedia di lingkungan seperti posix dan tidak portabel.
MacroMan
3
@MacroMan Tapi openssl_random_pseudo_bytes() adalah portable.
Ja͢ck
Jika Anda ingin menghapus karakter base64 ekstra, coba ini: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley
3
Ini tidak salah, tetapi saya akan menyarankan agar Anda membuang karakter yang tidak diinginkan. Lihat permintaan tarik ini di OAuth2 Server liga PHP , misalnya.
Scott Arciszewski
Ini adalah salah satu jawaban terbaik. Kasihan itu tidak memiliki lebih banyak dukungan. Saya akan merekomendasikan untuk mengedit jawaban Anda untuk penanganan karakter yang tidak diinginkan dengan lebih baik.
jcuenod
28

Berikut ini adalah satu-liner sederhana yang menghasilkan string acak yang benar tanpa perulangan level script atau penggunaan pustaka OpenSSL.

echo substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))), 1, 10);

Untuk memecahnya sehingga parameternya jelas

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

Metode ini bekerja dengan mengulangi daftar karakter secara acak, kemudian mengocok string gabungan, dan mengembalikan jumlah karakter yang ditentukan.

Anda selanjutnya dapat mengacak ini, dengan mengacak panjang string yang dikembalikan, menggantikannya $chrRandomLengthdengan mt_rand(8, 15)(untuk string acak antara 8 dan 15 karakter).

Kraang Prime
sumber
maaf untuk mengatakan tetapi ketika satu karakter dipilih probabilitasnya terjadi lagi tidak setinggi karakter lain masih tersisa di kolam. tidak ada keacakan yang sebenarnya di sini ...
The Surrican
@TheSurrican - Anda akan salah dalam pernyataan itu. Semua karakter memiliki probabilitas yang sama menggunakan algoritma ini, dan karenanya benar-benar acak. Ini dipastikan dengan mengulang string chrList $ chrRepeatMax, dan keajaiban benar-benar terjadi di str_shuffle yang menentukan keacakan.
Kraang Prime
Semua karakter hanya akan muncul sekali dan sangat rentan terhadap dugaan bruteforce
Venimus
@venimus Itu salah. String char digandakan untuk sebanyak karakter yang Anda inginkan (lihat $chrRepeatMaxdan $chrRepeatMin) - jadi string char 10, bisa (tidak mungkin, tetapi mungkin), menjadi "aaaaaaaaaa".
Kraang Prime
@SanuelJackson Maaf saya ketinggalan komentar. Saya telah memberikan komentar pada jawaban yang salah. Kamu benar! Saya benar-benar menggunakan "trik" Anda, tetapi tidak menggunakan mt_rand, karena itu adalah IMHO tidak berguna. Itu tidak menambah entropi. Baru saja menggunakan const dengan panjang max.
venimus
25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Tada!

Nikmat
sumber
Perlu diingat sha1akan menghasilkan batas 40 karakter dan selalu huruf kecil.
fyrye
3
Jika string tidak acak, karakter tertentu akan muncul lebih sering daripada yang lain. Ini tidak bijaksana untuk menggunakan ini dalam kasus di mana Anda benar-benar ingin keacakan seperti kata sandi.
Kit Sunde
1
@ Kititunde - ya, dia tidak acak, rand () acak. Dan dia baik-baik saja untuk apa yang dibutuhkan di sini. OP tidak perlu tingkat keacakan kripto.
Davor
@ Nikmat rant()yang acak tidak masalah ketika dia tidak merata. Jika Anda memilih secara acak dari distribusi yang tidak rata, Anda mendapatkan distribusi yang tidak merata sama persis. Ini bukan keacakan "crypto level" yang saya soroti, jika itu masalahnya Anda tidak harus menggunakan rand()keduanya. Dibutuhkan upaya minimal untuk memetik dari distribusi yang merata seperti dalam jawaban yang diterima dan itu acak seperti rand () yang memang wajar.
Kit Sunde
@ Kititunde - itu benar-benar tidak membuat perbedaan pada akhirnya. Itulah definisi overengineering dan pelapisan emas.
Davor
24

Cara yang lebih baik untuk mengimplementasikan fungsi ini adalah:

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_randlebih acak menurut ini dan ini di PHP 7. randFungsi ini adalah alias mt_rand.

Rathienth Baskaran
sumber
1
Perhatian: mt_randtidak menghasilkan nilai yang aman secara kriptografis. Untuk itu Anda harus menggunakan PHP7 random_intatau random_bytes.
jchook
18

$randstringdalam lingkup fungsi tidak sama dengan ruang lingkup tempat Anda memanggilnya. Anda harus menetapkan nilai kembali ke variabel.

$randstring = RandomString();
echo $randstring;

Atau langsung gandakan nilai kembali:

echo RandomString();

Juga, dalam fungsi Anda, Anda memiliki sedikit kesalahan. Di dalam for loop, Anda perlu menggunakan .=agar setiap karakter ditambahkan ke string. Dengan menggunakan =Anda menimpanya dengan setiap karakter baru alih-alih menambahkan.

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

Pertama, Anda mendefinisikan alfabet yang ingin Anda gunakan:

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

Kemudian, gunakan openssl_random_pseudo_bytes()untuk menghasilkan data acak yang tepat:

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

Akhirnya, Anda menggunakan data acak ini untuk membuat kata sandi. Karena setiap karakter di $randomdapat chr(0)sampai chr(255), kode menggunakan sisa setelah pembagian nilai ordinalnya dengan $alphabet_lengthuntuk memastikan hanya karakter dari alfabet yang dipilih (perhatikan bahwa melakukan hal itu bias keacakan):

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

Atau, dan umumnya lebih baik, adalah dengan menggunakan RandomLib dan SecurityLib :

use SecurityLib\Strength;

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

$password = $generator->generateString(12, $alphabet);
Ja͢ck
sumber
Penggunaan operator modulo %akan menghasilkan output yang bias. Namun, +1 kuat untuk RandomLib. Jangan menemukan kembali roda.
Scott Arciszewski
1
Ya, fungsi random_int () yang baru bagus: D
Ja͢ck
11

Metode Pendek ..

Berikut adalah beberapa metode terpendek untuk menghasilkan string acak

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

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

echo str_shuffle(MD5(microtime()));
?>
Punit Gajjar
sumber
10

Saya telah menguji kinerja fungsi paling populer di sana, waktu yang diperlukan untuk menghasilkan 1'000'000 string 32 simbol pada kotak saya adalah:

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

Harap dicatat, tidak penting berapa lama itu sebenarnya tetapi mana yang lebih lambat dan mana yang lebih cepat sehingga Anda dapat memilih sesuai dengan kebutuhan Anda termasuk kesiapan kriptografi, dll.

substr () sekitar MD5 ditambahkan demi akurasi jika Anda membutuhkan string yang lebih pendek dari 32 simbol.

Demi jawaban: string tidak disatukan tetapi ditimpa dan hasil fungsi tidak disimpan.

Putnik
sumber
Saya pikir, jawaban terbaik itu. Terima kasih!
NSukonny
10

PHP 7+ Hasilkan byte acak yang aman secara kriptografis menggunakan fungsi random_bytes .

$bytes = random_bytes(16);
echo bin2hex($bytes);

Output yang mungkin

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ Hasilkan byte pseudo-acak menggunakan fungsi openssl_random_pseudo_bytes .

$bytes = openssl_random_pseudo_bytes(16);
echo bin2hex($bytes);

Output yang mungkin

e2d1254506fbb6cd842cd640333214ad


The Kasus penggunaan terbaik bisa

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

Output yang mungkin

ba8cc342bdf91143

Madan Sapkota
sumber
Ini tidak akan menghasilkan string dengan panjang yang diberikan
Timberman
@Timberman itu akan menghasilkan panjang yang tepat sekarang.
Madan Sapkota
9

Salah satu cara yang sangat cepat adalah melakukan sesuatu seperti:

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

Ini akan menghasilkan string acak dengan panjang 10 karakter. Tentu saja, beberapa orang mungkin mengatakan itu sedikit lebih berat di sisi perhitungan, tetapi saat ini prosesor dioptimalkan untuk menjalankan algoritma md5 atau sha256 dengan sangat cepat. Dan tentu saja, jika rand()fungsi mengembalikan nilai yang sama, hasilnya akan sama, memiliki peluang 1/32767 menjadi sama. Jika keamanan adalah masalah, maka ubah saja rand()kemt_rand()

Akatosh
sumber
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;
}
Руслан Ибрагимов
sumber
4
Ini tidak portabel; jika Anda mencoba menjalankan ini di lingkungan non-posix, itu akan menyebabkan kesalahan fatal.
Bryan Agee
7

Yang ini diambil dari sumber admin :

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

Adminer , alat manajemen basis data yang ditulis dalam PHP.

userlond
sumber
6

Fungsi pembantu dari kerangka 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);
}
artnikpro
sumber
4
"Seharusnya tidak dianggap cukup untuk kriptografi, dll." Ini harus sangat ditekankan.
Scott Arciszewski
4

Versi fungsi yang diedit berfungsi dengan baik, tetapi hanya ada satu masalah yang saya temukan: Anda menggunakan karakter yang salah untuk menyertakan $ karakter, jadi karakter 'kadang-kadang bagian dari string acak yang dihasilkan.

Untuk memperbaiki ini, ubah:

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

untuk:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

Dengan cara ini hanya karakter tertutup yang digunakan, dan karakter 'tidak akan pernah menjadi bagian dari string acak yang dihasilkan.

bmcswee
sumber
4

Satu garis lainnya, yang menghasilkan string acak 10 karakter dengan huruf dan angka. Ini akan membuat array dengan range(sesuaikan parameter kedua untuk mengatur ukuran), lompati array ini dan berikan karakter ASCII acak (rentang 0-9 atau az), kemudian implode array untuk mendapatkan string.

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

Catatan: ini hanya berfungsi di PHP 5.3 dan yang lebih baru

kasimir
sumber
akhirnya solusi yang benar-benar acak bukan hash kembung integer acak 32 bit atau string yang dikocok ...
The Surrican
hanya ada satu masalah: angka lebih mungkin muncul sebagai karakter, yang tidak acak seperti yang saya ingin memilikinya. anyaway +1 untuk solusi terbaik di halaman ini. tweak itu dan itu sempurna.
The Surrican
tweak ... seperti ini? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth
4

Satu liner

Cepat untuk string besar dengan beberapa keunikan.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
Jacob Smith
sumber
md5(rand())adalah cara yang sangat tidak aman untuk menghasilkan angka acak.
Scott Arciszewski
1
string dengan panjang X dan beberapa keunikan adalah tujuannya. keacakan sebenarnya bukan maksudnya.
Jacob Smith
3

Saya menyukai komentar terakhir yang menggunakan openssl_random_pseudo_bytes, tapi itu bukan solusi bagi saya karena saya masih harus menghapus karakter yang tidak saya inginkan, dan saya tidak bisa mendapatkan string set panjang. Inilah solusi saya ...

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;
}
RKaneKnight
sumber
3
function randomString($length = 5) {
    return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
Anjith KP
sumber
3

Inilah solusi satu baris sederhana saya untuk menghasilkan kata sandi acak ramah yang digunakan, tidak termasuk karakter yang mirip seperti "1" dan "l", "O" dan "0", dll ... di sini adalah 5 karakter tetapi Anda dapat dengan mudah ubah saja:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);
rAthus
sumber
Ini sempurna untuk membuat string ID acak untuk dipanggil nanti di jquery. IDK jika latihannya bagus tapi ini banyak membantu saya, tanpa menggunakan untuk seperti jawaban yang diterima ...
Rodrigo Zuluaga
3

Ini solusi lain.

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

PS. Saya menggunakan PHP 7.2 di Ubuntu.

Umair Khan
sumber
2

Cara lain untuk menghasilkan string acak di PHP adalah:

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);
Akhilraj NS
sumber
2

Inilah cara saya melakukannya untuk mendapatkan kunci acak unik unik:

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

Anda dapat menggunakan waktu () karena ini adalah cap waktu Unix dan selalu unik dibandingkan dengan acak lainnya yang disebutkan di atas. Anda kemudian dapat menghasilkan md5sum itu dan mengambil panjang yang Anda inginkan dari MD5 yang dihasilkan string . Dalam hal ini saya menggunakan 10 karakter, dan saya bisa menggunakan string yang lebih panjang jika saya ingin membuatnya lebih unik.

Saya harap ini membantu.

sherpa
sumber
2
Tentu saja, time()jauh dari unik: itu akan mengembalikan nilai yang sama berulang-ulang sampai ujung kedua saat ini. Apa yang benar-benar memberikan beberapa keacakan di sini adalah str_shuffle()— sisa kode hanya mengurangi sampel untuk memilih karakter.
Álvaro González
1
jadi apa yang Anda lakukan pada dasarnya adalah mengaduk-aduk integer 32 bit. tidak banyak entropi di sini ...
The Surrican
2
Seorang penyerang dapat menebak nilai yang dikembalikan oleh time()(itu hanya cap waktu), itu adalah sumber keacakan yang lemah.
AL
2

Parametrised one-liner hanya menggunakan fungsi asli PHP , bekerja sejak 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))))))
pengguna10099
sumber