PHP rastgele dize oluşturucu


814

Ben PHP rastgele bir dize oluşturmaya çalışıyorum ve ben kesinlikle bu ile hiçbir çıktı olsun:

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

    RandomString();
    echo $randstring;

Neyi yanlış yapıyorum?


241
Kısa dize oluşturmak için bir satır çözümüm substr (md5 (rand ()), 0, 7); iyi şanslar ...
tasmaniski

5
@tasmaniski .. Çözümünüz iyi .. Ama daha az rastgele! Örneğinizde, oluşturulabilen rastgele dizelerin sayısı tamsayı büyüklüğü ile sınırlıdır. (2 ^ 32) max. Diğer çözüm durumunda (62 ^ 8) üretebilirsiniz .. Daha büyük dizeler istiyorsam, ayrı dizelerin sayısı max 2 ^ 32'de kalır, ancak diğer çözüm (62 ^ n) 'ye yükselir ..
Manu

9
Oluşturulan her yeni karakteri dizeye eklemeyi unuttunuz. Sadece olduğu gibi üzerine yazıyorsunuz. $ Randstring olmalıdır. = $ Karakterler ..
Spock

3
@CaptainLightning Kabul edilen cevabı daha güvenli olanlardan biri için değiştirebilir misiniz? :)
Scott Arciszewski

2
strlen($characters)=> strlen($characters) - 1- dize uzunluğu 1 ile başlar
Zippp

Yanıtlar:


1393

Bu soruyu özellikle cevaplamak için iki sorun var:

  1. $randstring yankılandığınızda kapsam dahilinde değildir.
  2. Karakterler döngü içinde bir araya getirilmiyor.

İşte düzeltmeleri içeren bir kod snippet'i:

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

Rastgele dizeyi aşağıdaki çağrı ile çıktılayın:

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

Bunun tahmin edilebilir rastgele dizeler oluşturduğunu lütfen unutmayın. Güvenli belirteçler oluşturmak istiyorsanız, bu yanıta bakın .


34
@FranciscoPresencia, Bir döngüyü karşılaştırma durumunda bir yöntem çağırmak gibi ekstra bir değişkeni "israf etmek" daha iyidir.
Rico Sonntag

200
Tüm bu işler, neden sadece bir şey değil substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH

4
Kod için teşekkürler, ama lütfen değişim rand()için mt_rand(). Metodunu kullandım ve isimlerle bir ton çarpışma yaşadım .
Nate

5
@FranciscoPresencia bunun ne kadar korkunç verimsiz olduğu hakkında bir fikrin var mı? Her yineleme için bir dizenin uzunluğunu iki kez kontrol ediyorsunuz! Döngünün içindeki strlen, döngüye girmeden önce bir değişkende önbelleğe alınmalıdır.
developerbmw

4
Bu iyi bir çözüm değil. Oluşturduğu dizeler öngörülebilir olacaktır. :(
Scott Arciszewski

370

Not: kriptografi amaçları için uygun olmayan str_shuffle()dahili kullanımlar rand()(örneğin rastgele şifreler oluşturmak). Bunun yerine güvenli bir rasgele sayı üreteci istiyorsunuz . Ayrıca karakterlerin tekrarlanmasına da izin vermez.

Bir yol daha.

GÜNCELLENDİ (şimdi bu herhangi bir dize uzunluğu oluşturur):

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

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

Bu kadar. :)


64
En kısa cevap için +1 :). Ancak her kullanım durumu için en iyi cevap değil. Bu kod, her karakterin bir kereden fazla görünmeyeceği dizeler çıkarır (böylece kaba kuvvet saldırıları için zayıflar) ve 62 karakterden uzun bir şey vermez.
David

17
Bunu yapma, son derece zayıf. Rastgele dizenizi ne kadar uzun yaparsanız, o kadar zayıf olacaktır.
Abhi Beckert

23
Zayıf olabilir, ancak hızlı ve kolaydır. Kullanım durumuna bağlı olarak, bu iyi - kullandım çünkü güvenlik veya güce ihtiyacım yoktu; çabuk ateşlenen bir karışık. Bir birim testi yazıyorum ve bu bana test etmek için uygun rastgele bir giriş veriyor.
SDC

23
@FranciscoPresencia güvenli olmamasının nedeni, aynı karakteri asla iki kez kullanmamasıdır. Bu onu korkunç bir şifre üreticisi yapar . Lütfen herkes oy vermekten vazgeçiyor, kesinlikle güvensizdir, asla kullanılmamalıdır. Şifre uzadıkça, daha önce kullanılan herhangi bir karakteri test etmeyi zahmet etmediğiniz için kaba kuvvetle test etmeniz gereken karakter sayısı kısalır.
Abhi Beckert

8
@FranciscoPresencia: Bunu rastgele şifreler için kullanmaktan kaçınma hakkındaki yorumlarınızı destekliyorum. Ancak, bu cevabın bire bir olmaması gerektiğine katılmıyorum. Rastgele dizeler (bu sorunun orijinal konusu) oluşturmak için etkili bir tek satırlık çözüm olduğu için bu seçeneği artı-one'd var.
bwright

331

Bu sorunun birçok yanıtı var, ancak bunların hiçbiri Şifreli Olarak Güvenli Sahte Rastgele Sayı Üreticisi (CSPRNG) kullanmıyor.

Basit, güvenli ve doğru cevap RandomLib kullanmak ve tekerleği yeniden icat etmemek.

Kendi çözümünüzü icat etmekte ısrar edenler için, PHP 7.0.0 random_int()bu amacı sağlayacaktır ; hala PHP 5.x kullanıyorsanız, PHP 7'ye yükseltmeden önce bile yeni API'yi kullanabilmeniz içinrandom_int() bir PHP 5 çoklu dolgusu yazdık .

PHP'de güvenli tamsayılar oluşturmak önemsiz bir iş değildir. Üretimde evde yetiştirilen bir algoritmayı dağıtmadan önce her zaman yerleşik StackExchange şifreleme uzmanlarınıza danışmalısınız .

Güvenli bir tamsayı oluşturucu ile CSPRNG ile rastgele bir dize oluşturmak parkta bir yürüyüştür.

Güvenli, Rastgele Bir Dize Oluşturma

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

Kullanımı :

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

Demo : https://3v4l.org/IMJGF (PHP 5 hatalarını yoksay; random_compat gerekir)


3
Fonksiyonun başında $keyspace = str_shuffle($keyspace );daha fazla güvenlik için ekleyin
Jevgenij Dmitrijev

13
"Daha fazla güvenlik için" ile ne demek istiyorsun? Zaten güvenli bir rasgele sayı üreteci kullanıyoruz.
Scott Arciszewski

5
@JGEstiot Güvenli rasgele dizeler oluşturmak için kriptografik olarak güvenli rasgelelik gerekir. "PHP'de rastgele dizeler nasıl oluşturulur" araması yapan biri, güvenli bir yanıtla güvensiz bir cevaptan daha iyi sunulur.
Scott Arciszewski

1
@ Scott Arciszewski Rastgele dizeler her oluşturduğunuzda kriptografik olarak rastgele dizeler oluşturmanıza gerek yoktur. Soru rastgele dizeler oluşturmakla ilgiliydi ve bunun güvenlikle ilgisi yok. Dizenin güvenliğe duyarlı bir bağlamda kullanılacağını varsaydınız ve sorunun özünü algılayan bir karmaşıklık katmanı eklediniz.
JG Estiot

45
Kullanılması random_int()yerine rand()veya mt_rand()geliştirici için hiçbir karmaşıklık ekler. Aynı zamanda onlara daha fazla güvenlik sağlar. Hızlı çözümler arayan StackOverflow'a gelen insanlar, oluşturdukları şeyin güvenli olup olmayacağını bilmeyebilirler. Onlara varsayılan olarak güvenli cevaplar verirsek, kendi bakış açılarına göre tamamen kazara olsa bile daha güvenli bir İnternet oluştururlar. Neden bu hedefe karşı çıkmak benim için bir gizem.
Scott Arciszewski

156

Bu, 20 karakter uzunluğunda onaltılık bir dize oluşturur:

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

PHP 7'de ( 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'ya kadar kriptografik olarak güçlü bir algoritma kullanmadığını lütfen unutmayın . İlgili hata: bugs.php.net/bug.php?id=70014
acidtv

Ayrıca, bunun yapabileceği en küçük dize 2 uzunluğunda olduğunu unutmayın. 1 veya daha az bayt uzunluğu openssl_random_pseudo_bytes()geçerseniz hiçbir şey geri alamazsınız. Ayrıca, not kullanırken o bin2hex(openssl_random_pseudo_bytes($length / 2))size tamsayılar ile çalışıyorsanız bu yana, otomatik olarak modulo kaldıracak ve 2. So sonraki en düşük birden kullanacak, $length = 19uzunluğu 18 dizesi üretecek
Nathan F.

Öneri yoluyla açılabilir dosya içeriğinin olarak kullanmak için fgets($fp, 1024): ve çok uzun çizgilerle sorunları var her dosya editörü function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }Set $splitiçin nullbunun tek astar dönmelidir eğer. Bununla her iki durum için de kullanabilirsiniz.
17'de mgutt

Ben gerçekten PHP 7 için random_bytes çözümü gibi, ama karakter belirli bir sayı olmak için dize gerekiyorsa böyle bir şey olurdu? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programcı

Bu kesinlikle şüphesiz en iyi çözümdür. Çok az yer kaplar ve anlaşılması çok kolaydır.
Matthew Campbell

92

@tasmaniski: Cevabınız benim için çalıştı. Aynı problemi yaşadım ve aynı cevabı arayanlar için bunu öneririm. İşte @tasmaniski'den:

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

Rastgele bir sayı oluşturmamızı gösteren bir youtube videosu


6
dizeniz yalnızca rastgele bir tamsayıyı temel alıyorsa, neden yalnızca rastgele tamsayıyı kullanmıyorsunuz? samanlık, hash ederek daha derine inmez ... ve hash'ınızı keserek aslında başlamak zorunda olduğunuz küçük entropiyi deminish eder.
Surrican

4
Unutmayın, md530 karakter sınırlaması ve her zaman küçük harfler kullanılır.
fyrye

3
Ayrıca, rand () kriptografi için kullanılmamalıdır. Kriyografik olarak ses dizesi oluşturmak istiyorsanız openssl_random_pseudo_bytes komutunu kullanın .
mattkgross

md5(rand())sadece 2 ^ 32 olası değer sunar. Bu, ortalama olarak 2 ^ 16 rastgele dizeden sonra birinin tekrarlanmasını bekleyeceğiniz anlamına gelir.
Scott Arciszewski

2
Peki .. Ben OP "güvenli rastgele dizeleri" hakkında konuşmuyor bahis olur. Bu çözüm, doğru kullanım durumları için kompakt, kolay ve hatırlanması kolay bir çözümdür . Ve, olası çarpışmalara dikkat etmeniz gerekiyorsa, neden rastgele dizeye zaman damgası eklemeyin / eklemeyin? :)
Erenor Paz

46

Uygulamanıza bağlı olarak (şifre oluşturmak istedim),

$string = base64_encode(openssl_random_pseudo_bytes(30));

Base64 olduğundan, istenen karakterleri içerebilir =veya içerebilir -. Daha uzun bir dize oluşturabilir, daha sonra bunları kaldırmak için filtreleyebilir ve kırpabilirsiniz.

openssl_random_pseudo_bytesphp uygun rasgele bir sayı oluşturmak için önerilen yol yolu gibi görünüyor. Neden randkullanmıyorum /dev/randombilmiyorum.


2
rand / dev / urandom kullanmaz, çünkü bu yalnızca posix ortamlarda kullanılabilir ve taşınabilir değildir.
MacroMan

3
@MacroMan Ama openssl_random_pseudo_bytes() olan taşınabilir.
Ja͢ck

Ekstra base64 karakterlerini çıkarmak istiyorsanız, şunu deneyin: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley

3
Bu yanlış değil, ancak istenmeyen karakterleri nasıl attığınıza dikkat etmenizi öneririm. Örneğin , PHP liginin OAuth2 Sunucusundaki bu çekme isteğine bakın .
Scott Arciszewski

Bu en iyi cevaplardan biri. Yazık ki daha fazla desteği yok. Yine de istenmeyen karakterlerin daha iyi işlenmesi için cevabınızı düzenlemenizi tavsiye ederim.
jcuenod

28

Burada, herhangi bir komut dosyası düzeyinde döngü veya OpenSSL kitaplıkları kullanılmadan gerçek bir rastgele dize oluşturan basit bir satırlık vardır.

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

Parametreleri netleştirmek için parçalamak için

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

Bu yöntem, karakter listesini rastgele tekrarlayarak çalışır, ardından birleştirilmiş dizeyi karıştırır ve belirtilen karakter sayısını döndürür.

Bunu, döndürülen dizenin uzunluğunu rasgele değiştirerek $chrRandomLength, mt_rand(8, 15)(8 ile 15 karakter arasında rastgele bir dize için) ile değiştirerek daha da rastgele yapabilirsiniz.


söylemek için üzgünüm ama bir karakter kap seçtikten sonra tekrar oluşma olasılığı havuzda kalan diğer karakterler kadar yüksek değil. burada gerçek bir rastgelelik yok ...
Surrican

@TheSurrican - Bu ifade yanlış olur. Tüm karakterler bu algoritmayı kullanarak eşit olasılığa sahiptir ve bu yüzden gerçekten rastgeledir. Bu, chrList $ chrRepeatMax dizesini tekrarlayarak sağlanır ve sihir, gerçekten rasgeleliği belirleyen str_shuffle'da gerçekleşir.
Kraang Prime

Tüm karakter yalnızca bir kez görünür ve bruteforce tahminine çok yatkındır
venimus

@venimus Bu yanlış. Karakter dizisi istediğiniz kadar karakter için kopyalanır (bkz. $chrRepeatMaxVe $chrRepeatMin) - 10 karakter dizesi (olası değil, ancak olası) "aaaaaaaaaa" olabilir.
Kraang Prime

@SanuelJackson Üzgünüm özledim-yorumladı. Yorumu yanlış cevaba verdim. Haklısın! Aslında "hile" nizi kullandım ama mt_rand kullanmadım, çünkü işe yaramaz IMHO. Entropiye eklenmez. Sadece maksimum uzunlukta const kullanılır.
venimus

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

Tada!


Unutmayın, sha140 karakter sınırlaması ve her zaman küçük harfler kullanılır.
fyrye

3
sha1 dizeleri rastgele değildir, bazı karakterler diğerlerinden daha sık görülür. Parolalar gibi rasgele bir rastgele olmasını istediğiniz durumlarda bunu kullanmak akıllıca olmaz.
Kit Sunde

1
@KitSunde - evet, sha rastgele değil, rand () rastgele. Ve sha burada ihtiyaç duyulan şeyler için gayet iyi. OP'nin kripto rasgelelik seviyesine ihtiyacı yoktur.
Davor

@Daha dengeli rant()olmak, eşit olarak dağıtılmadığında önemli değildir. Eğer eşit olmayan bir dağılımdan rastgele seçerseniz, aynı eşit olmayan dağılım elde edersiniz. Vurguladığım "kripto seviyesi" rasgeleliği değil, bu durumda da kullanmamalısınız rand(). Kabul edilen cevapta olduğu gibi eşit bir dağılımdan koparmak için çok az çaba harcanır ve rand () kadar rasgele olduğu kadar makul.
Kit Sunde

@KitSunde - sonunda hiçbir fark yaratmaz. Bu, tamamen mühendislik ve altın kaplamanın tanımıdır.
Davor

24

Bu işlevi uygulamanın daha iyi bir yolu:

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_randgöre daha rasgele , bu ve bu PHP 7'de randfonksiyonu bir takma mt_rand.


1
Dikkat: mt_randkriptografik olarak güvenli değerler oluşturmaz. Bunun için PHP7 random_intveya kullanmalısınız random_bytes.
jchook

18

$randstringişlev kapsamı, onu çağırdığınız kapsamla aynı değildir. Dönüş değerini bir değişkene atamanız gerekir.

$randstring = RandomString();
echo $randstring;

Ya da sadece dönüş değerini doğrudan yankılayın:

echo RandomString();

Ayrıca, işlevinizde küçük bir hata var. For döngüsü içinde, .=her karakter dizeye eklenecek şekilde kullanmanız gerekir . Bunu kullanarak =, eklemek yerine her yeni karakterle üzerine yazıyorsunuz.

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

14

İlk olarak, kullanmak istediğiniz alfabeyi tanımlarsınız:

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

Ardından, openssl_random_pseudo_bytes()uygun rastgele veriler oluşturmak için kullanın :

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

Son olarak, bu rastgele verileri şifreyi oluşturmak için kullanırsınız. İçindeki her karakter sonrasına kadar $randomolabileceğinden , kod yalnızca alfabedeki karakterlerin seçildiğinden emin olmak için sıra değerinin bölünmesinden sonra kalanını kullanır (bunu yapmak rasgele sapma gösterir):chr(0)chr(255)$alphabet_length

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

Alternatif olarak ve genellikle daha iyisi, RandomLib ve SecurityLib kullanmaktır :

use SecurityLib\Strength;

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

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

Modulo operatörünün kullanımı %yanlı çıktı üretecektir. Ancak, RandomLib için güçlü +1. Tekerleği yeniden icat etme.
Scott Arciszewski

1
Evet, yeni random_int () işlevi güzel: D
Ja͢ck

11

Kısa Yöntemler ..

İşte rastgele dizeyi oluşturmak için bazı en kısa yöntem

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

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

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

10

Orada en popüler fonksiyonların performansını test ettim, kutumda 32 sembolün 1'000'000 dizesini oluşturmak için gereken zaman:

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

Kriptografiye hazır olma gibi gereksinimlerinize göre seçim yapabilmeniz için gerçekte ne kadar sürdüğünün önemli olmadığını, hangisinin daha yavaş ve hangisinin daha hızlı olduğunu lütfen unutmayın.

32 sembolden daha kısa dizgeye ihtiyacınız varsa, doğruluk amacıyla substr () MD5 eklenmiştir.

Cevap uğruna: dize bitiştirilmedi ancak üzerine yazıldı ve işlevin sonucu kaydedilmedi.


Bence, bu en iyi cevap. Teşekkürler!
NSukonny

10

PHP 7+ random_bytes işlevini kullanarak kriptografik olarak güvenli rastgele baytlar üretir .

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

Olası çıktı

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ openssl_random_pseudo_bytes işlevini kullanarak sözde rasgele baytlar oluşturur .

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

Olası çıktı

e2d1254506fbb6cd842cd640333214ad


En iyi kullanım durumu olabilir

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

Olası çıktı

ba8cc342bdf91143


Bu, belirtilen uzunlukta bir dize oluşturmaz
Timberman

@ Timberman şimdi tam uzunluğu üretecek.
Madan Sapkota

9

Çok hızlı bir yol şuna benzer:

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

Bu, 10 karakter uzunluğunda rastgele bir dize oluşturur. Tabii ki, bazıları hesaplama tarafında biraz daha ağır olduğunu söyleyebilir, ancak günümüzde işlemciler md5 veya sha256 algoritmasını çok hızlı çalıştırmak için optimize edilmiştir. Ve elbette, rand()işlev aynı değeri döndürürse, sonuç aynı olacaktır ve 1/32767 aynı olma şansına sahip olacaktır. Güvenlik sorunu varsa, o zaman sadece değiştirmek rand()içinmt_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
Bu taşınabilir değildir; bunu herhangi bir posix dışı ortamda çalıştırmayı denerseniz, önemli bir hataya neden olur.
Bryan Agee

7

Bu yönetici kaynaklarından alınmıştır :

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

Yönetici , PHP ile yazılmış veritabanı yönetim aracı.


6

Laravel 5 çerçevesinden yardımcı fonksiyon

/**
 * 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
"Kriptografi vb. İçin yeterli görülmemelidir." Bu çok vurgulanmalıdır.
Scott Arciszewski


4

İşlevin düzenlenmiş sürümü iyi çalışıyor, ancak bulduğum tek bir sorun var: $ karakterlerini içine almak için yanlış karakteri kullandınız, bu yüzden 'karakteri bazen üretilen rastgele dizenin bir parçası.

Bunu düzeltmek için değiştirin:

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

için:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

Bu şekilde yalnızca ekteki karakterler kullanılır ve 'karakteri hiçbir zaman üretilen rastgele dizenin bir parçası olmaz.


4

Harf ve rakam içeren 10 karakterlik rastgele bir dize oluşturan başka bir tek astar. range(Boyutu ayarlamak için ikinci parametreyi ayarlayın) ile bir dizi oluşturur , bu dizi üzerinde döngüler oluşturur ve rastgele bir ASCII karakteri (0-9 veya az aralığı) atar, sonra bir dize almak için diziyi yerleştirir.

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

Not: Bu yalnızca PHP 5.3 ve sonraki sürümlerinde çalışır


nihayet gerçekten rastgele bir çözüm 32 bit rastgele tam sayı ya da karıştırılmış bir dize şişirilmiş karma değil ...
Surrican

sadece bir sorun var: sayılar karakter olarak ortaya çıkması muhtemeldir, ki ben sahip olmak isterdim kadar rastgele değildir. bu sayfadaki en iyi çözüm için her an +1. o ve onun mükemmel tweak.
Surrican

tweak ... böyle mi? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth

4

Bir astar.

Bazı benzersizliği olan büyük dizeler için hızlı.

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

md5(rand())rastgele bir sayı oluşturmak için korkunç derecede güvensiz bir yoldur.
Scott Arciszewski

1
X uzunluğunda ve biraz benzersiz olan bir dize niyettir. gerçek rastgelelik niyet değildir.
Jacob Smith


3

Openssl_random_pseudo_bytes kullanılan son yorum hoşuma gitti, ama yine de istemediğim karakterleri kaldırmak zorunda kaldım ve benim için bir uzunluk dizesi alamadım gibi bir çözüm değildi. İşte benim çözümüm ...

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

İşte "1" ve "l", "O" ve "0" gibi benzer karakterleri hariç tutmak için kullanımı kolay rastgele bir şifre oluşturmak için basit bir satır çözümüm ... burada 5 karakter var ama kolayca yapabilirsiniz tabii ki değiştir:

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

Bu, daha sonra jquery'de çağırmak için rasgele kimlik dizeleri oluşturmak için mükemmeldir. IDK iyi bir uygulama, ancak bu kabul edilen cevap gibi bir kullanmadan bana çok yardımcı oldu ...
Rodrigo Zuluaga

3

İşte başka bir çözüm.

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. Ubuntu üzerinde PHP 7.2 kullanıyorum.


2

PHP'de rastgele bir dize oluşturmanın başka bir yolu :

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

İşte nasıl gerçek bir benzersiz rastgele anahtar almak için yapıyorum:

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

Time () öğesini bir Unix zaman damgası olduğu ve yukarıda belirtilen diğer rastgele değerlerle karşılaştırıldığında her zaman benzersiz olduğu için kullanabilirsiniz. Daha sonra bunun md5sum'unu oluşturabilir ve oluşturulan MD5 dizesinden istediğiniz uzunluğu alabilirsiniz . Bu durumda 10 karakter kullanıyorum ve daha benzersiz hale getirmek istersem daha uzun bir dize kullanabilirim.

Umarım bu yardımcı olur.


2
Tabii ki, time()benzersiz olmaktan uzak: mevcut saniye bitene kadar aynı değeri tekrar tekrar döndürecektir. Burada gerçekten bazı rasgelelik sağlayan şey str_shuffle(), kodun geri kalanı sadece karakterleri seçmek için örneği azaltır.
Álvaro González

1
temelde yaptığınız şey 32 bitlik bir tamsayı etrafında karıştırmak. Burada entropi çok değil ...
Surrican

2
Bir saldırgan, döndürdüğü değeri tahmin edebilir time()(bu sadece bir zaman damgasıdır), zayıf bir rastgelelik kaynağıdır.
AL

2

PHP 5.1.0'dan beri çalışan, yalnızca PHP yerel işlevlerini kullanan parametreli tek astar

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))))))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.