MySQL ve php benzersiz bir metin alanı

6 Cevap php

Ben kullanarak bir tuzu yarattık; md5 (rand (0,10000000)); (Daha iyi bir yolu muhtemelen vardır?)

MYSQL bir metin alanı benzersiz yapmak mümkün olacaksa görünmüyor. Tuz Zaten bir önceki kullanıcı için kullanılır olmuştur Yani nasıl kontrol edebilirim?

Yoksa geçerli tarih / zaman dayalı tuz oluşturmak gerekir? Doğru aynı anda kayıt 2 kullanıcıları için imkansız gibi?

6 Cevap

Bir tuz, teklik uzunluğu ve öngörülebilirlik daha önemlidir. Sen saldırgan tuz vardır varsayalım.

Bir evrensel fark tanıtıcısı (UUID) iyi olurdu, ve php uniqueid() fonksiyonu için doc sayfada evrensel benzersiz tanımlayıcı oluşturmak örnekler vardır. Bir UUID nedenle bir varchar alan saklamak ve hiç çoğaltmaları olmamasını sağlamak için benzersiz bir dizin kullanabilirsiniz, insan okunabilir olduğunu da rasgele bir dize ve sabit bir uzunluk üzerinde bir avantaja sahiptir.

MD5 ile zaman karma sabit bir uzunluğa sahiptir ve insan okunabilir çünkü benzersiz değerler üretmek için yaygın bir yöntemdir. Ancak, sadece bir sabit uzunlukta rasgele dize oluşturmak ve altıgen şeklinde kendiniz kodlamak daha mantıklı. Onlar geri dönüşümlü olması için tasarlanmış konum olarak sağlamalarının teklik çok için tasarlanmış değildir. MD5 daha SHA1 daha az çarpışmalar olacak olsa bir karma işlevi kullanarak, çarpışmalar garanti eder.

Tuz daha uzun, daha çok evrensel özgü olduğu, çünkü tuz uzunluğu gerçekten sadece bir faktördür.

MySQL indeksler uzunluğu kısıtlı metin alanları vardır, onlar karakter / varchar alanları yapmak otomatik gibi tüm alan gitmez, bu yüzden metin alanları bir 'benzersiz' tuşunu kullanmak için pratik bir yolu yoktur.

MySQL tarafından oluşturulan karma saklıyorsanız, o metin gerekmez - sahiptir sonuçları düz metin vardır, bu yüzden sadece bir sabit uzunlukta karakter alanını kullanın:

mysql> select length(md5('a')), length(sha1('a'));
+------------------+-------------------+
| length(md5('a')) | length(sha1('a')) |
+------------------+-------------------+
|               32 |                40 | 
+------------------+-------------------+

ve sonra bu alana benzersiz bir kısıtlama uygulayabilirsiniz.

md5 () kırık bir algoritma ve dokundu asla.

Bu sistem saatine dayalı olduğu için rand () biraz bozuldu.

Daha iyi bir yöntem:

function generateRandomKey()
{
    return base_convert(uniqid(mt_rand(), true), 16, 36);
}

Orada daha iyi bir yoludur ya da ben yanılıyorum Edit: Eğer, bana bunu yapmanın yolunu göstermek lütfen. Ben gerçekten ilgileniyorum, ve ben güvensiz oluyorum olmadığını bilmek istiyorum.

Eğer bir UUID oluşturmak için http://php.net/manual/en/function.uniqid.php gibi bir şey kullanabilirsiniz. veya timestamp de iyi bir - hatta belki de zaman damgası ve ip adresi ya da benzeri.

SHA1 kullanıcı kimliği ve datetime kullanarak tuz oluşturun.

Genellikle sık sık tuz dizeleri oluşturmak istemiyorum. Önce onları üretmek Yani, iyi bir iş yapmak gerekir. Daha uzun ve daha rasgele dizeleri iyidir.

function generateSalt($length = null)
{
  if (!is_int($length) || ($length < 1)) $length = 250;
  do {
    $salt[] = chr(mt_rand(0, 255));
  } while (--$length);
  return implode('', $salt);
}

Yeni şifre güncelleme sorgusu

update user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1;

Eğer şifre doğru olup olmadığını kontrol edin ve aynı zamanda kullanıcı verilerini alabilirsiniz.

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;