Kendi TinyURL oluşturma

12 Cevap php

Ben gereken bir şey olduğu gibi sadece bu great tutorial bulduk.

Ancak, göz yaptıktan sonra, bu verimsiz olabilir gibi görünüyor. Çalışır yolu önce onu gerçekten benzersiz olduğundan emin olmak için veritabanında varsa daha sonra kontrol benzersiz bir anahtar oluşturmak olduğunu. Ancak, büyük veritabanı hakkı, işlevi alır yavaş olur?

Bunun yerine, bu işlev için sipariş eklemek için bir yol var, düşünüyordum? Yani yapılması gereken tüm DB önceki girişi kontrol ve anahtarı artırmak olduğunu. Bu yüzden her zaman benzersiz olacak?

function generate_chars()

{

    $num_chars = 4; //max length of random chars
    $i = 0;
    $my_keys = "123456789abcdefghijklmnopqrstuvwxyz"; //keys to be chosen from
    $keys_length = strlen($my_keys);
    $url  = "";
    while($i<$num_chars)
    {
    	$rand_num = mt_rand(1, $keys_length-1);
    	$url .= $my_keys[$rand_num];
    	$i++;
    }
    return $url;
}

function isUnique($chars)

{
    //check the uniqueness of the chars
    global $link;
    $q = "SELECT * FROM `urls` WHERE `unique_chars`='".$chars."'";
    $r = mysql_query($q, $link);
    //echo mysql_num_rows($r); die();
    if( mysql_num_rows($r)>0 ): 
    	return false;
    else: 
    	return true;
    endif;
}

12 Cevap

Minik url insanlar o zaman sadece küçük url bağlantıları troll, çünkü rastgele işaretler kullanmak ister. "Nereye 2. gidiyor?" "Ah, serin!" "Nereye # 3 gidiyor?" "Hatta soğuk!" Siz rasgele karakterler yazabilirsiniz ancak bu geçerli bir değer vuracak düşüktür.

Tuşu (4 değerleri her olasılık 1679616 benzersiz değerleri verir * 5 size 60.466.176 verir, 36 olan) çarpışmalar şansını küçük (aslında, bu tasarımın istenen parçası) ve iyi bir SQL endeksi yapacak oldukça seyrek olduğu arama (onlar etrafında optimize yani gerçekten, bu url için birincil arama bulunuyor) önemsiz olabilir.

Eğer gerçekten arama ve sadece unse otomatik artış kaçınmak istiyorsanız geri dönüştürme yeteneği görünüşte rasgele karakter dizeye bir tamsayı döner bir işlev oluşturabilirsiniz. Yani "1" "54jcdn" olur ve "2" "pqmw21" olur. Base64 kodlama benzer, ancak ardışık karakterler kullanarak değil.

(*) Aslında az 36 karakter kullanarak gibi - tek kasalı, hiçbir ünlüler, ve hiçbir benzer karakterler (1, l, I). Bu yanlışlıkla yemin sözcükleri önler ve aynı zamanda daha kolay kimse başkasına değerini konuşmak için yapar. Hatta "O" için "0" kabul, birbirine benzer charactes haritası. Tamamen makine tabanlı iseniz daha büyük olanakları için üst ve alt harf ve tüm rakamları kullanabilirsiniz.

Veritabanı tablosunda, orada unique_chars alanında bir endeks olup, böylece yavaş veya verimsiz olurdu neden görmüyorum.

UNIQUE KEY `unique_chars` (`unique_chars`)

Eğer yavaş olabileceğini düşünüyorum bir şey erken optimizasyon yapmak için acele etmeyin.

Ayrıca, rasgele adresler yerine sıralı adresler üreten bir url kısaltma servisi bazı yarar olabilir.

Eğer rahatsız ediyorum neden bilmiyorum. Öğretici öncül bir "rastgele" URL yaratmak için olduğunu. Rasgele alan yeterince büyükse, o zaman sadece saf, aptal şans güvenebilirsiniz. Eğer rastgele karakter boşluk 62 karakter (A-Za-z0-9), kullandıkları 4 karakter, makul bir rasgele sayı üreteci verilen ise, 14.776.336 1 olan 1 4 ^ 62 olduğunu. Beş karakter 916.132.832 1'dir. Yani, bir çatışma, kelimenin tam anlamıyla, "milyarda 1" dir.

Belgeler doldurmak gibi Açıkçası, sizin oran bir çarpışma şansı için artar.

10.000 belgelerle, neredeyse 1 100,000 (yuvarlak sayılar için), 91613 1 bulunuyor.

Yani her yeni belge için, size slot makine üzerinde başka çekme tekrar DB isabet 1 91613 şansı var demektir.

Bu deterministik değildir. Bu rastgele bulunuyor. Şans. Teorik olarak, gerçekten, gerçekten kötü şans bir dize vurabilir ve sadece çarpışma sonrası çarpışmadan sonra çarpışma olsun. Ayrıca, bu, sonunda, doldurmak OLACAKTIR. Kaç URL'ler karma planlıyorsunuz?

1 91613 yılında oran yeterince iyi değilse, ancak, 6 karakter onu artırılması 10.000 belgeler için 5M fazla 1 yapar. Biz burada neredeyse LOTO oran bahsediyoruz.

Basitçe söylemek gerekirse, (7 karakter? 8?) Yeterince anahtar büyük yapmak ve varoluş dışında sorun oldukça fazla "dilekler" kendisini.

Eğer oluşturulan olduğunda Base36 olarak URL kodlamak ve ziyaret ettiğinde sonra çözülemiyor - ki tamamen veritabanını kaldırmak için izin verecek?

A pasajı Channel9:

The formula is simple, just turn the Entry ID of our post, which is a long into a short string by Base-36 encoding it and then stick 'http://ch9.ms/' onto the front of it. This produces reasonably short URLs, and can be computed at either end without any need for a database look up. The result, a URL like http://ch9.ms/A49H is then used in creating the twitter link.

Ben seri numaraları tek-tek base36 olarak üretmek için kullanılan bir alogirthm uygulayarak benzer bir sorun çözüldü. Ben kendi oredring of base36 characters hepsi özeldir vardı. Bu seri sayılar üreten beri ben çoğaltılması hakkında endişelenmenize gerek yoktu. Karmaşıklık ve sayısının rastlantısallığı [karakterler] ... çok kamu için sadece benim uygulama becuase onlar seri numaraları olduğunu base36 numaraları sipariş bağlıdır :)

Bu adamlar işlevlerini kontrol - http://www.pgregg.com/projects/php/base_conversion/base_conversion.php Kaynak - http://www.pgregg.com/projects/php/base_conversion/base_conversion.inc.phps

Sen 62, çağrı tabanına 554.512 dönüştürmek için, örneğin, istediğiniz herhangi bir kaideyi kullanabilirsiniz

$tiny = base_base2base(554512, 10, 62); ve değerlendirir $tiny = '2KFk'.

Yani, sadece veritabanı kaydının benzersiz kimliği geçmek.

Bir projede ben $sChars dizeden kaldırıldı birkaç karakter bu kullanılan ve tabanı 58 kullanıyorum. Eğer değerler tahmin etmek daha kolay olacak istiyorsanız da dize karakterleri yeniden düzenleyebilirsiniz.

Sen ders sadece adresler numaralandırma tarafından sipariş ekleyebilirsiniz:

http://mytinyfier.com/1
http://mytinyfier.com/2

ve benzerleri. Kare tuşuna (tabii ki olmalı) veritabanında endeksli Ama eğer, performans artırmak, en az asgari olurdu.

Veritabanı AUTOINCREMENT kullanın ve http://www.acuras.co.uk/articles/24-php-use-mysqlinsertid-to-get-the-last-entered-auto-increment-value tarafından tarif edildiği gibi, en son kimliği almak

Ben iki nedenden dolayı sipariş numaralandırma yapıyor rahatsız olmaz:

1) SQL sunuculara) doğru dizinleri verilen (örneğin karma çarpışmalar kontrol çok etkilidir

Kullanıcıların kolayca diğer kullanıcıların tinyurl kırıcıdır anlamaya mümkün olacak gibi 2) Bu, gizlilik zarar verebilir.

Belki bu biraz off-cevap olduğunu, ancak, always benzersiz anahtarları oluşturmak için benim genel kural basit md5 (time () * 100 + rand (0, 100)); Iki kişi aynı saniyede aynı hizmeti kullanıyorsanız, bunlar aynı sonucu (nie imkansız) alacak bir 100,000 şansı var.

O dedi, md5 (rand (0, n)) çok çalışıyor.

Bu işe yarayabilir, ancak sorunu başarmak için kolay yolu muhtemelen karma ile olacak. Teorik olarak, konuşma O'da çalışır (1) zaman karma olduğu gibi, sadece karma gerçekleştirmek için vardır, ve sonra değerini almak için veritabanına tek gerçek hit yapar. Ardından, karma çarpışmalar kontrol için komplikasyonlara tanıtmak istiyorum, ama bu tinyurl sağlayıcıların çoğu ne muhtemelen gibi görünüyor. Ve iyi bir hash fonksiyonu yazmak için korkunç zor değildir.

Sadece istediğiniz uzunlukta karma Döşeme değil misiniz?

$tinyURL = substr(md5($longURL . time()),0,4);

Verilen bu tüm dize uzunluğu kullanarak kadar sözde rasgelelik sağlamayabilir. Eğer time() ile birleştirilmiş uzun bir URL karma Ama, eğer bu yeterli olmaz mıydı? Bu yöntemi kullanarak Üzerine Düşünceler? Teşekkürler!