Bu anlamlı sözler olması gerekmez - Daha rastgele parola üretimi gibi, ama yakalamak - onlar benzersiz olmalıdır. Ben paket / ürün çeşit kod için bu kullanarak olacak. Mevcut en iyi yöntem hangisi? :)
Kohana metni kullanın,
http://docs.kohanaphp.com/helpers/text
Örneğin,
$prod_id = text::random('alpha', 7);
Eğer çerçeve kullanmak istemiyorsanız, sadece kodu kopyalayabilirsiniz. Orada güzellikler çok bulacaksınız.
Bu eşsiz ve rastgele iki elemanla birlikte dizileri oluşturmak için genellikle mümkün değildir: Açıkçası algoritma dikkate sırayla önce oluşturulan unsurları almak zorunda, bu yüzden bir sonraki olanlar gerçekten rastgele olmayacak benzersiz olması.
Bu nedenle en iyi bahis (özel durumda çok pahalı olabilir) çarpışmaları algılamak ve sadece yeniden denemek olacaktır.
Eğer sadece 7 karakter kısıtlı iseniz, çok yukarıda yapabileceğiniz bir şey yok:
$allowed_chars = 'abcdefghijklmnopqrstuvwxz';
$allowed_count = strlen($allowed_chars);
$password = null;
$password_length = 7;
while($password === null || already_exists($password)) {
$password = '';
for($i = 0; $i < $password_length; ++$i) {
$password .= $allowed_chars{mt_rand(0, $allowed_count - 1)};
}
}
Bu sonuçta size yeni bir şifre vermek gerekir.
Bununla birlikte, benzer durumlarda ben genellikle de popüler bir hash fonksiyonunun onaltılık temsil boyutu olur büyük bir parola boyutunu almak karşılaştı (örneğin md5
). Sonra kendiniz ve eğilimli daha az hata daha kolay yapabilirsiniz:
$password = time(); // even better if you have some other "random" input to use here
do {
$password = md5(time().$password);
}
while (already_exists($password));
Bu aynı zamanda daha büyük bir alan dizisi olan ilave bir avantaja sahiptir, bu nedenle daha az çarpışmalar olacaktır. Eğer "garanti" düşük çarpışma olasılığı ve dolayısıyla muhtemelen pahalı already_exists
işlevine az aramaları gelecekte üretecek şifreleri beklenen numaralarına göre karma işlevi boyutunu seçebilirsiniz.
Burada sağlamalarının veya döngüler olmadan yapabileceği bir yolu var:
$password = sprintf(
"%04s%03s",
base_convert(mt_rand(0, pow(36, 4) - 1), 10, 36),
base_convert(mt_rand(0, pow(36, 3) - 1), 10, 36)
);
Birkaç diğerleri de söylediğim gibi, teklik sağlanması daha karmaşık ve gereksiz olmalıdır. Bunu yapabileceğini basit yolu üretilen her şifre ile arttırılarak, sonunda fazladan karakterler eklemek olacaktır.
İşte rastgele görünüyor ve benzersiz olması ve gelecek zamanlar için 7 karakterden olması gereken bir şeydir:
echo base_convert(intval(microtime(true) * 10000), 10, 36);
S>
Ya da biraz daha fazla randomness ve daha az uniqueness ({[) (2]} ile 10000 saniye):
echo base_convert(mt_rand(1, 9) . intval(microtime(true) * 1000), 10, 36);
Veya (100 ve 10000 saniyede arası teklik) - bu muhtemelen en iyi seçenek:
echo base_convert(mt_rand(10, 99) . intval(microtime(true) * 100), 10, 36);
Veya (10 ve 10000 saniyede arasında benzersiz):
echo base_convert(mt_rand(100, 999) . intval(microtime(true) * 10), 10, 36);
Siz anladınız.
Bir rasgele alfanümerik (baz 36 = 0..9 + a..z
) 7 karakterden has to have a base 10 representation between 2176782336
ve 78364164095
strong> olan değeri, aşağıdaki kod parçasında bunu kanıtlıyor:
var_dump(base_convert('1000000', 36, 10)); // 2176782336
var_dump(base_convert('zzzzzzz', 36, 10)); // 78364164095
Biz olmayan bir yinelenen faktör güvenmek zorunda benzersiz olması için için, açık bir seçimdir time()
:
var_dump(time()); // 1273508728
var_dump(microtime(true)); // 1273508728.2883
Biz sadece saniyede 1 eşsiz bir kod minimum teklik faktörü sağlamak için isteseydik biz yapabiliriz:
var_dump(base_convert(time() * 2, 10, 36)); // 164ff8w
var_dump(base_convert(time() * 2 + 1, 10, 36)); // 164ff8x
var_dump(base_convert(time() * 2 + 2, 10, 36)); // 164ff8y
var_dump(base_convert(time() * 2 + 3, 10, 36)); // 164ff8z
Bu kodlar rasgele olmadığını fark edeceksiniz, ayrıca time()
(1273508728
) 2176782336
(daha az olduğunu fark edeceksiniz asgari taban 10 temsilidir 7 karakter kod), yani ben bunu neden var time() * 2
.
Şimdi rasgelelik ekleme ve PHP'nin eski sürümleri tamsayı sınırlamaları uyarken teklik faktörünü artırmak amacıyla bazı tarih matematik yapmanıza olanak sağlar (< 5.0
?):
var_dump(1 * 60 * 60); // 3600
var_dump(1 * 60 * 60 * 24); // 86400
var_dump(1 * 60 * 60 * 24 * 366); // 31622400
var_dump(1 * 60 * 60 * 24 * 366 * 10); // 316224000
var_dump(1 * 60 * 60 * 24 * 366 * 20); // 632448000
var_dump(1 * 60 * 60 * 24 * 366 * 30); // 948672000
var_dump(1 * 60 * 60 * 24 * 366 * 31); // 980294400
var_dump(PHP_INT_MAX); // 2147483647
PHP_INT_MAX
Ben şu açıkça PHP 5.3.1 'de çalışır çünkü tam PHP'nin son sürümlerinde değişti ne emin değilim ile ilgili olarak, maybe someone could shed some light into this:
var_dump(base_convert(PHP_INT_MAX, 10, 36)); // zik0zj
var_dump(base_convert(PHP_INT_MAX + 1, 10, 36)); // zik0zk
var_dump(base_convert(PHP_INT_MAX + 2, 10, 36)); // zik0zl
var_dump(base_convert(PHP_INT_MAX * 2, 10, 36)); // 1z141z2
var_dump(base_convert(PHP_INT_MAX * 2 + 1, 10, 36)); // 1z141z3
var_dump(base_convert(PHP_INT_MAX * 2 + 2, 10, 36)); // 1z141z4
Ben biraz burada benim rasyonalizasyon ile kayboldu ve ben sadece gerçekten hızlı bitiririm ben sıkıldım. Biz hemen hemen bütün baz 36 charset kullanmak ve saniyede 1 benzersiz kod teklik faktör garantili minimum güvenli generate sequential kodları for 3.16887646 years strong> bu kullanarak:
base_convert(mt_rand(22, 782) . substr(time(), 2), 10, 36);
Ben sadece yukarıda bazen biz bizim taban 36 charset biraz sınırlamak gerekir benzersiz sonuçlar üretmek amacıyla nedeniyle mt_rand()
ilk argümanına çoğaltılamaz değerleri döndürebilir fark:
base_convert(mt_rand(122, 782) . substr(time(), 2), 10, 36);
Yukarıdaki değerler onları biz microtime()
kullanabilirsiniz ama biz sadece bir teklik faktörü sağlamak rastgele görünmesi için, hala sıralı olduğunu unutmayın 10 codes per second for 3.8 months strong>:
base_convert(mt_rand(122, 782) . substr(number_format(microtime(true), 1, '', ''), 3), 10, 36);
Bu kısıtlamayla yeri vardır çünkü ben aslen antecipated daha zor olduğunu kanıtladı:
Biz yukarıdaki herhangi sayabilirsiniz varsa bu çok daha kolay olurdu ve ben bu daha da optimize edilebilir eminim ama dediğim gibi: Bu beni sıkıyor. Belki birisi Ben bıraktığı yerden bu kadar almak istiyorum. =) I'm hungry! =S
(: Birisi başka bir şifreyi bilmeden dayalı başkasının şifreyi tahmin etmek mümkün olmamalı yani) burada şifreleri söz önüne alındığında, ben güvenli bir yöntem gerekir kabul edeceğiz. Aşağıdaki kullanabilirsiniz:
Güvenlik bir sorun değilse, kendileri tarafından 1 ve 2 yeterli olacaktır adımlar. Güvenlik sorunu ise, hiç kimse ama kendinizi "MasterPassword" değerini bilir önemlidir.
İşte bu sorunu çözecek nasıl:
7 karakter 26 harf (ABC.. Z) bir, ya da 10 sayı (01 ... 9) olabileceğini düşünün. Bu 36 olası karakterleri kılar.
Uygulama yeni bir kod üretir, her zaman bu global bir değişken artırmak var. Bir "Hexatridecimal" dönüştürücü kullanarak ve dize geri kalanını oluşturan, dolgu karakterleri ekleyerek eşsiz bir dizeye Bu benzersiz numarayı açabilirsiniz.
Take a look at this link. I think this guy had the same problem as you: http://www.codemaxima.com/2010/04/the-hexatridecimal-numbering-system/
@ Michael Haren yorumuna +1. Sitenizde şifreleri benzersiz olması için bir kısıtlama olmamalıdır eğer.
Ben belirli bir parola kullanmayı deneyin ve ben zaten kullanımda çünkü ben bunu kullanamaz bir hata alırsanız, o zaman ben sistemde bazı kullanıcı bu parolayı var biliyorum. 1000 kullanıcı varsa sadece ben bu parolayı sahip birini bulmak önce 1000 diğer hesapların bir max denemek gerekir.
Gerçekten soruyu cevaplarken, ama bir açıklama daha fazla değildir. Yani bu CW işaretleme ediyorum.
bunu yapmak için benim en sevdiğim yoludur.
$pretrimmedrandom = md5(uniqid(mt_rand(),true));
$trimmed = substr($pretrimmedrandom ,0,7);
uniqid bir çok benzersiz rasgele dize oluşturmak için geçerli zaman kullanır. Sonuçları "3f456yg" benziyor.
Galen'in cevabı şifre her karakterin sadece bir kullanımını sağlar. Bu dizede değil çok bilgi. Gerçi basit bir değişiklik:
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$passwordlength = 7;
for ($x = 1; $x <= $passwordlength; $x++) {
$charlist .= $chars;
}
$temp_pw = substr( str_shuffle( $charlist ), 0, $passwordlength );