En az kopyalanma olasılığı ile tam 5 rastgele karakter dizisi oluşturmak istiyorum. Bunu yapmanın en iyi yolu ne olabilir? Teşekkürler.
En az kopyalanma olasılığı ile tam 5 rastgele karakter dizisi oluşturmak istiyorum. Bunu yapmanın en iyi yolu ne olabilir? Teşekkürler.
Random::alphanumericString($length)
, 0-9a-zA-Z içeren dizeleri kriptografik olarak güvenli rastgele verilerden elde edebilirsiniz.
Yanıtlar:
$rand = substr(md5(microtime()),rand(0,26),5);
En iyi tahminim olur - Siz de özel karakterler aramıyorsanız:
$seed = str_split('abcdefghijklmnopqrstuvwxyz'
.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.'0123456789!@#$%^&*()'); // and any other characters
shuffle($seed); // probably optional since array_is randomized; this may be redundant
$rand = '';
foreach (array_rand($seed, 5) as $k) $rand .= $seed[$k];
Ve saati temel alan biri için (artımlı olduğundan daha az çarpışma):
function incrementalHash($len = 5){
$charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$base = strlen($charset);
$result = '';
$now = explode(' ', microtime())[1];
while ($now >= $base){
$i = $now % $base;
$result = $charset[$i] . $result;
$now /= $base;
}
return substr($result, -5);
}
Not: artımlı, tahmin edilmesi daha kolay anlamına gelir; Bunu bir tuz veya doğrulama jetonu olarak kullanıyorsanız, kullanmayın. Bir "WCWyb" tuzu (şimdi) 5 saniye sonra "WCWyg" olduğu anlamına gelir)
md5()
Bununla birlikte, kullanmanın sorunu, 16 karakterlik bir diziden oluşan bir dizge elde etmenizdir (10 hane ve a
- f
, yani, karakter dizisi başına 4 bit). Bu, bazı amaçlar için yeterli olabilir, ancak kriptografik amaçlar için çok az olabilir (16 sembolden beş karakter = 16 ^ 5 = 20 bit = 1048576 olasılık).
array_rand($seed, 5)
değer değil dizi anahtarı döndürecektir, böylece kodunuz çalışmayacaktır
"
, '
ve ters bölü $charset
? Bu karakterleri dahil etmek için kaçış dizilerini kullanmam gerekir mi?
$len
giriş parametresini bile kullanmıyor ... unuttunuz mu?
Eğer for
döngüler sıkıntısı vardır, burada kullanımına ne gibi:
$s = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
str_shuffle('ab')
verir ab
veya verir ba
ama asla aa
. Bunun için izinleri eklemek str_repeat
. Ancak bununla birlikte, verdiğim çözüm gerçekten ciddi bir çözüm değil ... işe yarasa da.
l
, i
, 1
, 0
, O
, vb ve üzerinden 500 kuponları hiçbir çiftleri var.
Hızlı bir yol, uniqid işlevinin en uçucu karakterlerini kullanmaktır .
Örneğin:
$rand = substr(uniqid('', true), -5);
Bunu basitçe şu şekilde deneyebilirsiniz:
$length = 5;
$randomletter = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, $length);
daha fazla ayrıntı: http://forum.arnlweb.com/viewtopic.php?f=7&t=25
Aşağıdakiler, en az çoğaltma şansını sağlamalıdır ( mt_rand()
örneğin /dev/*random
, GUID'lerden veya GUID'lerden daha iyi bir rasgele sayı kaynağıyla değiştirmek isteyebilirsiniz ):
<?php
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$result = '';
for ($i = 0; $i < 5; $i++)
$result .= $characters[mt_rand(0, 61)];
?>
DÜZENLEME:
Güvenlik konusunda endişeleriniz varsa, gerçekten, do not kullanmak rand()
veya mt_rand()
, ve rasgele veri cihazı aslında üreten bir cihaz olduğunu doğrulamak rastgele veriler değil, normal bir dosya veya benzeri öngörülebilir bir şey /dev/zero
. mt_rand()
zararlı kabul edilen:
https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php
DÜZENLEME:
PHP'de OpenSSL desteğiniz varsa, şunları kullanabilirsiniz openssl_random_pseudo_bytes()
:
<?php
$length = 5;
$randomBytes = openssl_random_pseudo_bytes($length);
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$charactersLength = strlen($characters);
$result = '';
for ($i = 0; $i < $length; $i++)
$result .= $characters[ord($randomBytes[$i]) % $charactersLength];
?>
strlen()
Bir döngüde kullanmak , özellikle karakter setinin bu arada değişmeyeceğini zaten biliyorsanız, gereksiz bir ek yüktür.
Bunun için her zaman aynı işlevi kullanıyorum, genellikle şifre oluşturmak için. Kullanımı kolay ve kullanışlı.
function randPass($length, $strength=8) {
$vowels = 'aeuy';
$consonants = 'bdghjmnpqrstvz';
if ($strength >= 1) {
$consonants .= 'BDGHJLMNPQRSTVWXZ';
}
if ($strength >= 2) {
$vowels .= "AEUY";
}
if ($strength >= 4) {
$consonants .= '23456789';
}
if ($strength >= 8) {
$consonants .= '@#$%';
}
$password = '';
$alt = time() % 2;
for ($i = 0; $i < $length; $i++) {
if ($alt == 1) {
$password .= $consonants[(rand() % strlen($consonants))];
$alt = 0;
} else {
$password .= $vowels[(rand() % strlen($vowels))];
$alt = 1;
}
}
return $password;
}
Str_shuffle bunun için iyi bir kullanım olacak gibi görünüyor . İstediğiniz karakterlerle karıştırmayı tohumlayın.
$my_rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);
Yalnızca AF harflerini almanız sorun değilse, işte çözümüm:
str_pad(dechex(mt_rand(0, 0xFFFFF)), 5, '0', STR_PAD_LEFT);
Karma işlevlerin kullanılmasının, rastgele onaltılık rakamlar dizisi oluşturmak gibi basit bir görev için aşırı bir beceri olduğuna inanıyorum. dechex
+ mt_rand
aynı işi yapar, ancak gereksiz kriptografik çalışma yapmaz. str_pad
çıktı dizesinin 5 karakter uzunluğunu garanti eder (rastgele sayı 0x10000'den küçükse).
Yinelenen olasılık, mt_rand
güvenilirliğine bağlıdır . Mersenne Twister , yüksek kaliteli rastgelelikle bilinir, bu nedenle göreve tam olarak uymalıdır.
Ayrıca PHP'leri kullanmayı düşünene kadar bunu nasıl yapacağımı bilmiyordum array
. Ve bunun, dizilerle rastgele bir dizi veya sayı oluşturmanın en basit yolu olduğundan oldukça eminim. Kod:
function randstr ($len=10, $abc="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789") {
$letters = str_split($abc);
$str = "";
for ($i=0; $i<=$len; $i++) {
$str .= $letters[rand(0, count($letters)-1)];
};
return $str;
};
Bu işlevi şu şekilde kullanabilirsiniz
randstr(20) // returns a random 20 letter string
// Or like this
randstr(5, abc) // returns a random 5 letter string using the letters "abc"
Benzer Brad Christie bireyin cevabı, ancak kullanarak sha1
karakterler için alrorithm 0-9a-zA-Z
ve rastgele değer öneki:
$str = substr(sha1(mt_rand() . microtime()), mt_rand(0,35), 5);
Ancak tanımlı (izin verilen) bir karakter belirlediyseniz:
$validChars = array('0','1','2' /*...*/,'?','-','_','a','b','c' /*...*/);
$validCharsCount = count($validChars);
$str = '';
for ($i=0; $i<5; $i++) {
$str .= $validChars[rand(0,$validCharsCount - 1)];
}
** GÜNCELLEME **
As Archimedix işaret, bu kombinasyonun sayısı göz önüne alındığında karakter aralığı için düşük olduğundan, bir "çoğaltılamaz alma az ihtimalini" dönmek garantisini vermez. Karakter sayısını artırmanız veya dizede fazladan (özel) karakterlere izin vermeniz gerekir. Sanırım sizin durumunuzda ilk çözüm tercih edilebilir.
time()
1 milyon kat daha tahmin edilebilir microtime()
.
$str
.
˫§»⁋⅓
" vermeniz gerekiyorsa, onlara " " sadece daha güvenli olduğu için vermek istemezsiniz ... referans anahtarınızı 7 veya daha fazla karaktere yükseltirsiniz . (BTW: önceki yorumumdaki düzeltme, 5x36 karakter)
PHP'de iyi çalışıyor (php 5.4.4)
$seed = str_split('abcdefghijklmnopqrstuvwxyz');
$rand = array_rand($seed, 5);
$convert = array_map(function($n){
global $seed;
return $seed[$n];
},$rand);
$var = implode('',$convert);
echo $var;
Kaynak: Rastgele Karakterler Oluşturan PHP İşlevi
Bu basit PHP işlevi benim için çalıştı:
function cvf_ps_generate_random_code($length=10) {
$string = '';
// You can define your own characters here.
$characters = "23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
Kullanım:
echo cvf_ps_generate_random_code(5);
İşte benim random 5 cents
...
$random=function($a, $b) {
return(
substr(str_shuffle(('\\`)/|@'.
password_hash(mt_rand(0,999999),
PASSWORD_DEFAULT).'!*^&~(')),
$a, $b)
);
};
echo($random(0,5));
PHP'nin yeni password_hash()
(*> = PHP 5.5) işlevi, oldukça uzun büyük harf ve küçük harf karakterleri ve sayıları oluşturma işini yapıyor.
İki concat. password_hash
$ random işlevi içinde önceki ve sonraki dizeler değişiklik için uygundur.
İçin Paramteres $random()
* ($ a $, b) aslında substr()
parametreleri. :)
NOT: Bunun bir işlev olması gerekmez, normal değişken de olabilir .. kötü bir tek satırlayıcı gibi, şöyle:
$random=(substr(str_shuffle(('\\`)/|@'.password_hash(mt_rand(0,999999), PASSWORD_DEFAULT).'!*^&~(')), 0, 5));
echo($random);
function CaracteresAleatorios( $Tamanno, $Opciones) {
$Opciones = empty($Opciones) ? array(0, 1, 2) : $Opciones;
$Tamanno = empty($Tamanno) ? 16 : $Tamanno;
$Caracteres=array("0123456789","abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ");
$Caracteres= implode("",array_intersect_key($Caracteres, array_flip($Opciones)));
$CantidadCaracteres=strlen($Caracteres)-1;
$CaracteresAleatorios='';
for ($k = 0; $k < $Tamanno; $k++) {
$CaracteresAleatorios.=$Caracteres[rand(0, $CantidadCaracteres)];
}
return $CaracteresAleatorios;
}
Ben uzaktayım bunu kullanıyorum:
<?php function fRand($len) {
$str = '';
$a = "abcdefghijklmnopqrstuvwxyz0123456789";
$b = str_split($a);
for ($i=1; $i <= $len ; $i++) {
$str .= $b[rand(0,strlen($a)-1)];
}
return $str;
} ?>
Onu çağırdığınızda, ipin uzunluğunu belirler.
<?php echo fRand([LENGHT]); ?>
Ayrıca dizedeki olası karakterleri de değiştirebilirsiniz $a
.
0-9a-zA-Z
mı yoksa sadece ?