Nasıl YouTube gibi, benzersiz kimlikler oluşturabilirim?

13 Cevap php

Hep merak etmişimdir nasıl ve onlar bunu neden ... bir örnek: http://youtube.com/watch?v=DnAMjq0haic

Nasıl bu kimlikleri hiçbir çiftleri vardır böyle oluşturulur, ve bu sayısal kimliği artan basit bir otomobil olan üzerinde ne avantajı var?

Nasıl bir kısa tutmak yok ama yine de teklik bulunuyor tutmak? Dize uniqid oluşturur oldukça uzun.

13 Cevap

base62 veya base64 birincil anahtarın değeri daha sonra başka bir alanda saklayın kodlamak.

Birincil anahtar 12443 = 3EH için örnek base62

emin im youtube kullanıyor yüzden biraz boşluk, kazandırır.

(A-Za-z0-9) ve PK veya benzersiz tanımlayıcı kodlamak bir base62 yapıyor anahtar zaten var olmadığını görmek için kontrol etmek zorunda yükünü önlemek olacaktır :)

Otomatik artan bir kolaylıkla taranabilir. Bu tahmin edilemez ve bu nedenle sıralı sürünerek edilemez.

Ben (SO URL'ler benzer) bir çift url formatında olacak öneririz:

yoursite.com/video_idkey/url_friendly_video_title

Eğer id ve url başlığı hem Gerekirse, daha sonra 0001, 0002, 0003, vb gibi basit numaralarını kullanabilirsiniz

Bu anahtarları oluşturuluyor çok basit olabilir. Daha entropi ile 13 karakter veya 23 oluşturmak için PHP uniqid() işlevini kullanabilirsiniz.

Kevin van Zonneveld tam olarak bunu yapmak için mükemmel bir article dahil olmak üzere bir PHP işlevini yazmıştır. Onun yaklaşımı, bu konuyu araştırma yaparken buldum en iyisidir.

Onun işlevi oldukça akıllıdır. O kadar sorunlu karakterler (örneğin ünlüler, ya da O ve 0 karışıklığı önlemek için) çıkarılabilir sabit $ dizin değişkeni kullanır. Ayrıca kolayca tahmin edilebilir değildir ki kimlikleri karartmak için bir seçenek vardır.

Kısa URL'leri istediğiniz ve öngörülebilirlik bir endişe değil, yapabilirsiniz convert the auto-incrementing ID to a higher base.

Gibi bir şey kullanmayı düşünün:

$ Id = base64_encode (md5 (uniqid (), true));

uniqid size benzersiz bir tanımlayıcı alacak. MD5 size 128 bit sonuç vererek onu yayacaktır. Size 6 civarında 23 karakterden ağırlığında web üzerinde kullanıma uygun bir tanımlayıcı karakter başına bit, ve tahmin hesaplama dirençli verecek Base 64 şifreleme. Eğer MD5 SHA1 veya daha yüksek daha paranoyak Ugrade olmak istiyorsanız.

Bunu yapmak için bir yolu, benzersiz girişi ile bir hash fonksiyonu ile her zaman.

örnek (Eğer php Therfore ile soru etiketlediniz):

$uniqueID = null
do {
  $uniqueID = sha1( $fileName + date() );
} while ( !isUnique($uniqueID) )

PHP bu kimlikleri oluşturmak için bir kütüphane olmalıdır. Değilse, bunu uygulamak zor değil.

Avantajı farklı sunucu kaynaklarını yeniden düzenlemek veya birleştirmeye çalıştığınızda daha sonra, adı çakışmalarını yok olmasıdır. Sayısal kimlikleri ile anlaşmazlıkları çözmek için bunlardan bazılarını değiştirmek zorunda kalacak ve bu SEO hit giden URL değişimine neden olacaktır.

Bu kadar çok yapmanız gereken ne bağlıdır. Eşsiz nasıl 'eşsiz' olduğunu? Eğer kimlikleri benzersiz kadar hizmet vermekteyiz, ve onlar da sizin DB şey demek istiyorsun? eğer öyleyse, bir sıralı # Tamam olabilir.

Öte yandan, sıralı # 's kullanırsanız birisi sistematik numaraları aracılığıyla yineleme tarafından içerik çalmak olabilir.

Benzersiz dosya adları üretecektir dosya sistemi komutları vardır - bu kullanabilirsiniz.

Veya GUID ait.

Hash SHA-1 veya MD5 gibi fonksiyonları ve GUID'lerin sonuçları muhtemelen istemediğiniz bir şey olduğu, çok uzun olma eğilimindedir. (Bunu özellikle bir örnek olarak YouTube söz ettik: Onların tanımlayıcılar bile barındıran bazillion videoları ile nispeten kısa kalmak.)

Bu URL'ler içine koyarak, başka bir üssü haline, sen perde arkasında kullanarak sayısal kimlikleri, dönüştürme içine bakmak isteyebilirsiniz neden olduğunu. Flickr mesela kanonik kısa URL'ler için Base58 kullanır. Bu konuda detayları burada mevcuttur: http://www.flickr.com/groups/api/discuss/72157616713786392/. Eğer genel bir çözüm arıyorsanız, PEAR paketi Mathe_Basex bakabilirsiniz.

Hatta başka bir baz, kimlikleri hala uygulama dışında tahmin edilebilir unutmayın.

Ben benzer bir sorunu vardı - Ben veritabanında birincil id vardı, ama ben bunları kullanıcıya maruz istemiyordu - bunun yerine karma çeşit göstermek için çok daha iyi olurdu. Yani, ben hashids yazdı.

Dokümantasyon: http://www.hashids.org/php/

Sos: https://github.com/ivanakimov/hashids.php

Bu sınıf ile oluşturulan sağlamalarının benzersiz ve decryptable vardır. Diğerleri (büyük bir sorun değil, ama yine de bir "iyi-to-var") ve karma şifresini olamaz, bu yüzden özel bir tuz değer sağlayabilir.

Lütfen bu yapacağını bir sayıda şifrelemek için:

require('lib/Hashids/Hashids.php');

$hashids = new Hashids\Hashids('this is my salt');
$hash = $hashids->encrypt(123);

Sizin $hash şimdi olacaktır: YDx

Ayrıca böylece sağlamalarının uzun olabilir kurucusuna ikinci parametre olarak asgari karma uzunluğunu ayarlayabilirsiniz. Karmaşık bir kümelenmiş sistemi varsa veya hatta tek bir karma içine birkaç numara şifrelemek olabilir:

$hash = $hashids->encrypt(2, 456); /* aXupK */

(Örneğin, kümedeki bir kullanıcı varsa 2 ve birincil kimliği ile bir nesne 456) Şifre çözme aynı şekilde çalışmaktadır:

$numbers = $hashids->decrypt('aXupK');

$numbers sonra olacaktır: [2, 456].

Bu konuda iyi bir şey bile veritabanında bu karmaları saklamak zorunda değilsiniz. Siz istek gelir kez url karma almak ve anında onu şifresini olabilir - ve sonra (tabii ki hız bir avantaj olduğu) veritabanı birincil id yıllardan tarafından çekin.

Çıkışı ile aynı - Eğer yolda id şifrelemek ve kullanıcıya karma görüntüleyebilirsiniz.

EDIT:

  1. Doc web sitesi ve kod kaynağını hem de içerecek şekilde adresler değişti
  2. Ana lib güncelleştirmeleri ayarlamak için değiştirdi örnek kod (geçerli PHP lib sürümü 0.3.0 olan - lib iyileştirilmesi için tüm açık kaynak topluluğuna sayesinde)

Ben bir formülü yok ama biz ben olduğum bir projede bunu. (Ben paylaşmak olamaz). Ama biz temelde bir kerede bir karakter oluşturmak ve dize eklemek.

Biz tamamlanmış dize var, biz veritabanı karşı kontrol edin. Başka varsa, biz onunla gitmek. Bir yinelenen ise, biz işlemini başlatmak. Çok karmaşık değildir.

Avantajı bir GUID bu tahmin.

Bu NOT PHP ama php ya da Javascript ve olduğu gibi dönüştürülebilir böylece php benzersiz bir id ihtiyacı ne olursa olsun yayınlamak gibi .. o kullanılabilecek sunucu yavaşlaması gerek kalmadan clinetside.

Burada sınırlı eşsiz kimlikleri oluşturmak için bir yoldur

9 007 199 254 740 992 unique id's

o zaman 9 charachters döndürür.

burada iE2XnNGpF olan 9 007 199 254 740 992

You can encode a long Number and then decode the 9char generated String and it returns the number.

basically this function uses the 62base index Math.log() and Math.Power to get the right index based on the number.. i would explain more about the function but ifound it some time ago and can't find the site anymore and it toke me very long time to get how this works... anyway i rewrote the function from 0.. and this one is 2-3 times faster than the one that i found. i looped through 10million checking if the number is the same as the enc dec process and it toke 33sec with this one and the other one 90sec.

var UID={
 ix:'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
 enc:function(N){
  N<=9007199254740992||(alert('OMG no more uid\'s'));
  var M=Math,F=M.floor,L=M.log,P=M.pow,r='',I=UID.ix,l=I.length,i;
  for(i=F(L(N)/L(l));i>=0;i--){
   r+=I.substr((F(N/P(l,i))%l),1)
  };
  return UID.rev(new Array(10-r.length).join('a')+r)
 },
 dec:function(S){
  var S=UID.rev(S),r=0,i,l=S.length,I=UID.ix,j=I.length,P=Math.pow;
  for(i=0;i<=(l-1);i++){r+=I.indexOf(S.substr(i,1))*P(j,(l-1-i))};
  return r
 },
 rev:function(a){return a.split('').reverse().join('')}
};

I de s '0 olarak oluşturulan dize s' a ekli 9 karakter dizesi istedim.

Bir sen bir Number geçmek gerekiyor numarası ve bir dize kodlamak.

var uniqueId=UID.enc(9007199254740992);

Tekrar sayıları çözmek için, String oluşturulan 9char geçmesi gerekiyor

var id=UID.dec(uniqueId);

burada bazı sayılar

console.log(UID.enc(9007199254740992))//9 biliardi o 9 milioni di miliardi
console.log(UID.enc(1)) //baaaaaaaa 
console.log(UID.enc(10)) //kaaaaaaaa 
console.log(UID.enc(100)) //Cbaaaaaaa 
console.log(UID.enc(1000)) //iqaaaaaaa 
console.log(UID.enc(10000)) //sBcaaaaaa 
console.log(UID.enc(100000)) //Ua0aaaaaa 
console.log(UID.enc(1000000)) //cjmeaaaaa
console.log(UID.enc(10000000)) //u2XFaaaaa
console.log(UID.enc(100000000)) //o9ALgaaaa 
console.log(UID.enc(1000000000)) //qGTFfbaaa
console.log(UID.enc(10000000000)) //AOYKUkaaa 
console.log(UID.enc(100000000000)) //OjO9jLbaa
console.log(UID.enc(1000000000000)) //eAfM7Braa 
console.log(UID.enc(10000000000000)) //EOTK1dQca
console.log(UID.enc(100000000000000)) //2ka938y2a

As you can see there are alot of a's and you don't want that... so just start with a high number. let's say you DB id is 1 .. just add 100000000000000 so that you have 100000000000001

ve benzersiz id YouTube'un id benziyor 3ka938y2a

i diğer 8907199254740992 benzersiz id yerine getirmek kolay olduğunu sanmıyorum