Veritabanı id engellemeyecek

10 Cevap php

Ben otomatik artış bir birincil anahtara sahip bir tablo var. Ben birincil anahtar ile ilişkili bir görüntü olmasını istiyorum ama birincil anahtar ortaya istemiyorum. Görüntüleri adlandırma bir şey gibi:

$filename = md5($primarykey + $secret_string) . '.jpg';

iyi bir çözüm olabilir mi?

Ben bir çarpışma ve bir dosya üzerine yazılır olabileceğini endişe duyuyorum.

Tabii diğer seçenek bir dosya olarak yok ve veritabanında depolamak kontrol, rastgele bir dize oluşturmak için ... ama id onun gereksiz eğer ek veri depolamak için tercih.

Diğer seçenek 1, 2 = b ama bir randomize sırada örneğin 1 = x 2 = m ... ama sonra orada deşifre olma şansı ... artı md5 muhtemelen olacaktır ile = mantıksal bir dönüşüm youtube url tarzı eg herhangi bir youtube url fonksiyonu daha hafiftir.

Öyle bir çarpışma olasılığı başlık ne ben iki milyondan fazla kayıtları ile uğraşıyorum tahmin ediyorum? Hangi seçenek alacağını ya da daha iyi bir yaklaşım düşünebilirsiniz?

10 Cevap

Eğer varsa iki seçenek gerçekten var:

  • Şey & üret Hiçbir çarpışmaları doğrulayın
  • Şey & üret Hiçbir çarpışmalar için umut

You can generally use the following options: - A hash - A randomly generated string - A UUID

Hash If you're choosing a hash, choose something with a low incidence of collisions. Also, when doing a hash consider why you want to obscure DB ids. It won't take long for somebody to figure out your hashes if you're hashing plain numbers, you absolutely need to salt it. The advantages of a salted hash is quick generation and low chance of collisions (in small cases absolutely no need to verify for these, so faster inserts). The downside is that any proper implementation will be SHA256 or better, which means it's long. You can do some hex-conversions if you want to save DB/Index space, that may be more then you want.

Random String This you can generate to any length that suits you, of any character set or numbers a-Z0-9. This also means "more" data in a shorter string that's used in URIs, REQUEST data, etc. The downside is that you have to check if it's in the database.

A UUID Like a hash, fast to generate, fairly low chance of collisions and can be modified to be "less" ugly then pure outputs.

My Suggestion Don't do it. I've had to deal with this before on a very large implementation that grew from being a very small implementation. Eventually you start doing "smart" things like creating totally unique identifiers (e.g. content type + your identifier) and start seeing some value in it, but then you have to deal with scale. Scaling this is very difficult. DBs are optimized for ids as primary keys, there's a surprising large amount of thought you would need to put into this if you wanted it to scale vertically. If you must, only use it for external client interactions.

Bir linear congruential generator kullanın. Düzgün değerleri seçerseniz, o zaman çok büyük bir dönemine pseudorandom dizisine sahip olacaktır. Çarpışmalar, ama not bu sadece bir şaşırtmaca yöntemidir ve (ama ben sizin için ne arıyorsanız değil varsayalım) herhangi bir gerçek güvenlik vermeyecektir.

Verdiğiniz Kod iyi iş yapmak için uygundur. Sen çarpışmalar, veritabanları kullandığı herhangi bir başka aynı md5 karma sonuçlanacaktır hiçbir tamsayı hakkında endişelenmenize gerek yok.

Eğer olmak istiyorsan really emin: Buraya bir litte test komut dosyası olan ;)

<?php
for($i = 0; $i < 1000000; ++$i) {
    $hash = md5($i);
    if(isset($x[$hash])) { die("COLLISION!"); }
    $x[$hash] = true;
}        }
echo "All is well";

Daha karmaşık bir çözüm zaman kaybı gibi görünüyor ama kısa kimlikleri istediğiniz durumda her resim kısa bir rasgele oluşturulmuş id verebilir (ise şu durumda ve alrealy nesil zamanında kullanılmış eğer kontrol ve başka birini oluşturabilir)

I would guess I am dealing with over two million records so what is the likely hood of a collision?

Göre Wikipedia, en az bir çarpışma olması için% 50 olasılık almak için en fazla 2 * 10 ^ 19 kayıt gerekir, bu yüzden endişelenmenize gerek yok derim.

Sunucu belirsiz id gelen veritabanı kaydı aramak için obscuring geri dönüşümlü olması gerekiyor çünkü tipik URL'leri veritabanı kimlikleri engellemeyecek için aslında, id şifrelemek olacaktır. Reverzibilite dosya adları haritalama veritabanı kimlikleri dava için önemli olmayabilir, ama aynı zamanda çarpışma olasılığını ortadan kaldıracak basit bir desen var.

Siz base64 veya onaltılık kodlamayı kullanan, örneğin ASCII şifrelenmiş verileri dönüştürmek isteyeceksiniz:

base64_encode(encrypt(id, secret_key))

Ve çözme:

decrypt(base64_decode(id), secret_key)

(Yukarıdaki PHP içinde uygun işlevleri bulmak gerekecek, pseudo-kod)

Sen şifreleme için çok süslü bir şey gerekmez. DES gibi basit bir blok şifreleme yeterli olacaktır.

Ben Base64 kullanma hakkında katılıyorum. Ayrıca bir Guid kullanabilirsiniz. Ya da sadece yaptığım tabloda, dosya adını depolar.

Ek olarak, yetim dosyaları önlemek için dikkat çekmek.

Tanımı gereği sağlamalarının teklik sağlamak değil gibi MD5 gibi bir karma algoritması (onlar değerlerle sınırlı sayıda karma oluşturmak), bunun için iyi bir çözüm değildir.

Ne istediğiniz bir şifreleme olduğunu. Javax.crypto.Cipher bir göz atın.

Eğer bir sütun ekleyebilirsiniz, tabloda bir UNIQUE sütun olarak bir GUID eklemek ve Anahtar adı olarak <GUID>.jpg kullanın. GUID algoritmaları yakın gelecekte de çiftleri üretmek gerektiğini, ancak just-in-case UNIQUE kısıtlaması, bu yakalamak istiyorsunuz.

Eğer kimliğini kullanmak istiyorum, ancak kimliği ortaya, ve çarpışma riski düşük istiyorum istemiyorsanız; bir seçenek kimliği bir karma kullanmak olacaktır. Her fotoğraf için benzersiz - karma, tutarlı, geri dönüşümsüz ve (2 32 imsi kullanılan karma bağlı olarak büyük veri setlerini hariç) olacaktır. Eğer söz bunun temel fikir var gibi:

$filename = md5($primarykey + $secret_string) . '.jpg';

Seçtiğiniz bir karma daha iyi bir algoritma için MD5 yerine. Tercihen büyük çıkışı ile bir şeydir. Yorumlarına yanıt olarak makaleleri çeşitli kaymağını dayanarak, o SHA512 ya da benzer bir şey bir daha uygun olacağını görünüyor.

Sadece birincil anahtarın bir karma kullanın. Orada bir çarpışma olma şansı veeeery düşüktür.