PHP içinde rasgele bir anahtar oluşturmak için en iyi yolu nedir?

10 Cevap php

I (2 ila 1000 +) seçilen uzunluk yazdırılabilir ACSII karakterleri ile rasgele bir anahtar üretecek bir yeniden işlev oluşturmak için arıyorum. Ben yazdırılabilir ASCII karakterleri düşünüyorum 33-126 olacaktır. Bu anahtar aynı milisaniye oluşturulan if (yani uniqid() çalışmayacaktır), sadece benzersiz, tamamen benzersiz olması gerekmez.

I chr() ve mt_rand() işe yarayabilecek bir arada düşünüyorum.

Bu gitmek için yolu var mı, yoksa başka bir şey en iyi yöntem nedir?

Bir uzunluk parametresi yoktur, çünkü Edit: uniqid() aynı zamanda PHP verir ne olursa olsun sadece, çalışmaz.

My Idea: Bu ben ile geldi budur:

function GenerateKey($length = 16) {
    $key = '';

    for($i = 0; $i < $length; $i ++) {
        $key .= chr(mt_rand(33, 126));
    }

    return $key;
}

Bu herhangi bir sorun var mı?

Another Edit: diğer soruların çoğu parola üretimi ile anlaşma. Ben karakter daha geniş bir istiyorum ve ben 1 l vs umurumda değil. Ben mümkün anahtarların azami sayısı mümkün olmak istiyorum.

10 Cevap

Şahsen ben sha1(microtime(true).mt_rand(10000,90000)) kullanmak ister ama özelleştirilebilir bir yaklaşım daha fazla arıyoruz, bu nedenle bu işlevini deneyin (sizin isteğinize bir değişiklik olduğu this answer):

function rand_char($length) {
  $random = '';
  for ($i = 0; $i < $length; $i++) {
    $random .= chr(mt_rand(33, 126));
  }
  return $random;
}

Yine de, bu muhtemelen) (uniqid çok daha yavaş olacak, md5 (), veya sha1 ().

Öncelikle bu var gibi Edit: Üzgünüm, görünüyor. : D

Edit 2: PHP 5 ve eAccelerator (uzun kod bahane) ile benim Debian makinede bir güzel küçük bir test yapmaya karar verdi:

function rand_char($length) {
  $random = '';
  for ($i = 0; $i < $length; $i++) {
    $random .= chr(mt_rand(33, 126));
  }
  return $random;
}

function rand_sha1($length) {
  $max = ceil($length / 40);
  $random = '';
  for ($i = 0; $i < $max; $i ++) {
    $random .= sha1(microtime(true).mt_rand(10000,90000));
  }
  return substr($random, 0, $length);
}

function rand_md5($length) {
  $max = ceil($length / 32);
  $random = '';
  for ($i = 0; $i < $max; $i ++) {
    $random .= md5(microtime(true).mt_rand(10000,90000));
  }
  return substr($random, 0, $length);
}

$a = microtime(true);
for ($x = 0; $x < 1000; $x++)
  $temp = rand_char(1000);

echo "Rand:\t".(microtime(true) - $a)."\n";

$a = microtime(true);
for ($x = 0; $x < 1000; $x++)
  $temp = rand_sha1(1000);

echo "SHA-1:\t".(microtime(true) - $a)."\n";

$a = microtime(true);
for ($x = 0; $x < 1000; $x++)
  $temp = rand_md5(1000);

echo "MD5:\t".(microtime(true) - $a)."\n";

Sonuçlar:

Rand:   2.09621596336
SHA-1:  0.611464977264
MD5:    0.618473052979

Yani benim önerim, size hız (ama tam charset) isterseniz, (henüz .. ben test etmedim) MD5, SHA-1, ya da uniqid sadık olmaktır

Eğer (rastgele anahtarlar ne tahmin etmeye çalışırken bir belirlenen saldırganın var mı?) Şifreleme-gücü rastgeleliğine burayi cevapların hiçbiri yeterlidir. Zaman karma bir saldırganın büyük ölçüde bunların sunucu anahtarını üretilen düşünüyorum ve bu bir yıl içinde her milisaniye üzerinden arama kolay sefer tahmin ederek kendi arama hızlandırmak, güvenli değildir, hatta bir emtia laptop (bir 35 var bit arama alanı). Onlar öğrenmek Ayrıca, bir zamanlar sadece "genişletmek" için bir hash fonksiyonu sayesinde uniqid() sonuçlarını veya diğer bazı zayıf rastgele kaynak çalıştırmak için öneri saldırganın arama zor yapmaz-bu tehlikeli olduğunu size Bu yaptım.

Eğer gerçekten kripto düzey güvenlik ihtiyacınız varsa, dev / random / okumalısınız, aşağıdaki kod herhangi bir POSIX uyumlu sistemi (Windows'da bir şey ama) sizin için çalışması gerekir:

#Generate a random key from /dev/random
function get_key($bit_length = 128){
    $fp = @fopen('/dev/random','rb');
    if ($fp !== FALSE) {
        $key = substr(base64_encode(@fread($fp,($bit_length + 7) / 8)), 0, (($bit_length + 5) / 6)  - 2);
        @fclose($fp);
        return $key;
    }
    return null;
}

Eğer biraz daha hızlı gerekiyorsa, bunun yerine 'dev / urandom' dan okuyabilirsiniz.

Hala sadece ihtiyacınız karakter sayısına değerini genişletmek için bazı ek işlemler yapmak () uniqid kullanabilirsiniz.

Örneğin, 32 karaktere kadar genişletmek için, yapabileceğin

$id = md5(uniqid());

64 karaktere genişletmek için, sadece bu yüzden gibi, md5 md5 append

$first = md5(uniqid());
$id = $first . md5($first);

Eğer 32 katları daha az gerekiyorsa, daha sonra, gerekli trucate.

Bu çarpışmalar içine çalıştırabilir mümkün, ama oldukça düşüktür. Bu konuda paranoyak iseniz, sadece aynı fikri kullanabilirsiniz, ama çuf uniqid() AES gibi simetrik bir şifre aracılığıyla yerine bunu karma.

Ben, bir şey gibi yapmak istiyorum

$randkey = hash('sha-256', 
  uniqid(serialize($_SERVER), true));

Uniqid dahil edilmesi () bu sunucudan özgü sağlamak için çalışır. $ _SERVER Dizgeleştirme başka bir sunucuda aynı karma oluşturmak değildir sağlamak için çalışır. Çünkü SHA-256, bir çarpışma üzerine tökezleyerek gülünç küçük şans 'çalışır' demek.

Bu 64 karakter olduğunu unutmayın. O yutmak için çok fazla ise, varsayılan hex yerine Base64 olabilir. Yaklaşık 43 karaktere çökertir.

$randkey = base64_encode(hash('sha-256', 
  uniqid(serialize($_SERVER), true), true));

PunBB gelen fonksiyon .. ben bunu sevdi!

// Generate a random key of length $len
function random_key($len, $readable = false, $hash = false)
{
    $key = '';

    if ($hash)
        $key = substr(sha1(uniqid(rand(), true)), 0, $len);
    else if ($readable)
    {
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

        for ($i = 0; $i < $len; ++$i)
            $key .= substr($chars, (mt_rand() % strlen($chars)), 1);
    }
    else
        for ($i = 0; $i < $len; ++$i)
            $key .= chr(mt_rand(33, 126));

    return $key;
}

See if the php code on this post helps: Generate Random Strings Using PHP

Temelde sabit bir dizi karakter (ler) den seçilmiş sabit uzunlukta bir karakter rastgele bir dizi döner. Sen harf / küçük harf karakterleri, basamak ve sembollerin bir karışımı ile rasgele bir dize oluşturmak ya da özel karakter örneğin ayarlamak belirtmek için giriş parametreleri düzenleyebilirsiniz hexa-ondalık basamak sadece.

(Yazı kopyalanan) basit rastgele dizeleri için örnek çıktı:

EVH46H33
7248YPJP
F02W4M5E
0X550PII

(Şifreler kullanmak için) karmaşık rasgele dizeleri için örnek çıktı:

mczt0:Rm
2dwvJp!v
wo9iVk@b
c5xmx:xR

Ben onlar için $ more_entropy seçeneği eklendi beri () uniqid bakmadım şüpheli. Yani aynı milisaniye şeyi giderir.

that question sizin için ilgi olacağını mı?

I uniqid() sizin için ve aksi takdirde mutlaka bir benzersiz, aynı milisaniyede sayıda ama ne gerek bu durumda çalışmıyor neden emin değilim; Eğer aynı milisaniye içinde bir çarpışma olabilir o kadar hızlı ne ürettiğini? Ben çok zaman uniqid() sadece kendi sayı üretmek için gereken nedir merak ediyorum. İsterseniz, rastgele birkaç harf ile uniqid() fonksiyonu öneki parametresini kullanın ve güvenli olmalıdır.

Bu dosyayı üreten Eğer, tmpfile() or tempname() bakmak isteyebilirsiniz.

Her durumda, size ulaşmak için çalışıyoruz ne bağlı olarak, sadece döngü ve benzersiz kimliği zaten (file_exists, vb, bir dizi) alınır ve bu durumda eğer sadece bir tane oluşturmak olduğunu doğrulamak.


Ben tam olarak soruyu anlamadım emin değilim olarak da, ben senin farkını almak ise oldukça benzer ses bu diğer sorulara işaret eder:

Okunabilir bir insan, eşsiz bir id yapmak arıyorsanız ilki ilgi olacaktır. Rasgele sayılar ve MD5/SHA1 ile oynamak istiyorsanız, ikinci bir yararlı olabilir. Yine, ben uniqid() zaten aradığınız ne olabilir düşünüyorum rağmen.

md5(uniqid(mt_rand(), true));

Bu sütunda HEX veya İKİLİ şekilde depolanan sıkıca kodlamak HEX (0-9A-F) karakterler üretir, kullanabilirsiniz DAMGA (32) ama o kadar etkili değil. Açıkçası bu baskı güzel ve hiçbir komik karakterler outloud söylemek kolaydır.

Bu dünyada her bilgisayar bunları üreten sanki bir UUID olarak bilinir ve sen hiç, iki kez aynı birini oluşturabilir asla budur.

PS: Teknik olarak (SHA-256 ve substr kullanmak gerekir) daha kaliteli UUIDs oluşturmak için uzun 32 karakter şey.

$ Key = md5 (microtime () rand ().);

Bu tahmin ediliyor sadece 1/1000 'şans bırakır, çünkü tek başına microtime güvenli değildir.

Kendisi tarafından Rand da çok güvenli değil, ama onların bunları bir araya birleştirerek karma oldukça sağlam bir randomizasyon verir.