C# ile Google PageRank Bulma

Google‘ın PageRank uygulaması, web sitelerinin Google tarafından önemini bulmakta kullanılan bir algoritmadır.

Wikipedia’daki şu adresten, PageRank algoritması ile ilgili ayrıntılı bilgiye erişebilirsiniz.

Siz de sitenizin PageRank değerini http://www.prchecker.info adresinden bulabilirsiniz.

Yazacağımız uygulama ile, sitenizin Google PageRank değerini programatik olarak buldurabileceğiz.

Google sitelerin PageRank değerlerini, http://toolbarqueries.google.com/search adresine gönderilen sorgulara cevap olarak verebiliyor. Fakat sonuç alabilmemiz için bu adrese doğru parametreleri vermemiz gerekiyor, aksi halde HTTP403 : Forbidden hatası alıyoruz.

Parametreler:

  • features=Rank
  • client=navclient-auto
  • q=info:{adres}
  • ch={checksum} Checksum bilgisini hesaplamak için Google’ın yayınladığı bir algoritma var. Uygulamamızda, bu algoritmayı C# ile yazacağız.

Yukarıdaki resimde görünen arayüzü hazırladıktan sonra, projemize GooglePageRank isminde static class ekliyoruz.

GooglePageRank static class’ı üç tane static method’dan oluşuyor.

private static void Mix(ref uint a, ref uint b, ref uint c) { a -= b; a -= c; a ^= c >> 13; b -= c; b -= a; b ^= a << 8; c -= a; c -= b; c ^= b >> 13; a -= b; a -= c; a ^= c >> 12; b -= c; b -= a; b ^= a << 16; c -= a; c -= b; c ^= b >> 5; a -= b; a -= c; a ^= c >> 3; b -= c; b -= a; b ^= a << 10; c -= a; c -= b; c ^= b >> 15; }</pre>

private static string GoogleChecksum(string url)
{
    uint GoogleMagic = 0xE6359A60;

    uint a, b;
    uint c = GoogleMagic;

    a = b = 0x9E3779B9;

    int k = 0;
    int length = url.Length;

    while (length >= 12)
    {
        a += (uint)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));
        b += (uint)(url[k + 4] + (url[k + 5] << 8) + (url[k + 6] << 16) + (url[k + 7] << 24));
        c += (uint)(url[k + 8] + (url[k + 9] << 8) + (url[k + 10] << 16) + (url[k + 11] << 24));

        Mix(ref a, ref b, ref c);

        k += 12;
        length -= 12;
    }

    c += (uint)url.Length;

    switch (length)
    {
        case 11:
            c += (uint)(url[k + 10] << 24);
            goto case 10;
        case 10:
            c += (uint)(url[k + 9] << 16);
            goto case 9;
        case 9:
            c += (uint)(url[k + 8] << 8);
            goto case 8;
        case 8:
            b += (uint)(url[k + 7] << 24);
            goto case 7;
        case 7:
            b += (uint)(url[k + 6] << 16);
            goto case 6;
        case 6:
            b += (uint)(url[k + 5] << 8);
            goto case 5;
        case 5:
            b += (uint)(url[k + 4]);
            goto case 4;
        case 4:
            a += (uint)(url[k + 3] << 24);
            goto case 3;
        case 3:
            a += (uint)(url[k + 2] << 16);
            goto case 2;
        case 2:
            a += (uint)(url[k + 1] << 8);
            goto case 1;
        case 1:
            a += (uint)(url[k + 0]);
            break;
        default:
            break;
    }

    Mix(ref a, ref b, ref c);

    return string.Format("6{0}", c);
}
public static string PageRankHesapla(string adres)
{
    string checkSum = GoogleChecksum("info:" + adres);
    string url = "http://toolbarqueries.google.com/search?client=navclient-auto&ch=" + checkSum + "&features=Rank&q=info:" + adres;

    try
    {
        WebRequest request = WebRequest.Create(url);
        WebResponse response = request.GetResponse();

        StreamReader reader = new StreamReader(response.GetResponseStream());
        string data = reader.ReadToEnd();

        reader.Close();
        response.Close();

        if (data.IndexOf(':') != -1)
            data = data.Substring(data.LastIndexOf(':') + 1);

        return data;
    }
    catch (Exception)
    {
        return "-1";
    }
}


Şimdi yapmamız gereken, Butonun *Click* olayında, *GooglePageRank* static class'ının *PageRankHesapla* method'unu çağırmak ve dönen değeri Label'da göstermek.

Uygulamanın çalışır halini bu adresten indirebilirsiniz.

Code Challenge #1

Dün Emre (nam-ı diğer kara) arkadaşımla internette gezerken, bir youtube video’suna denk geldik. Emre’nin bilgisayarındaki hosts dosyasında güncel youtube ip adresleri olmadığı için videoyu izleyemedik.

Aklımıza, youtube domainine ait ip adreslerini otomatik olarak bulacak ve hosts dosyasını güncelleyecek bir uygulama yazmak geldi. Öğle yemeğine çıkmamıza 15 dakika olduğu için, bunu bir yarışa dönüştürmeye karar verdik.

İşte Yarışmanın Kuralları;

  • youtube.com, www.youtube.com, img.youtube.com alan adlarının ve v{1-24}.lscache{1-8}.c.youtube.com formatındaki alan adlarının ip adresleri otomatik olarak çözümlenecek
  • Domain adından IP adresini çözen bir servis kullanılacak (Ben böyle bir web service bulamadım, o yüzden http://www.hcidata.info/host2ip.cgi adresindeki formu kullandık)
  • Sonuç bilgisi C:\Windows\System32\drivers\etc\ altındaki hosts dosyasına otomatik olarak yazılacak
  • Uygulamayı yazma - test etme ve çalıştırma sonucunda, ilk kimin uygulaması hosts dosyasını güncellerse kazanmış olacak YoutubeHostDuzenleyici_2

Sizinde 15 dakikanız var, code challenge‘ımıza katılmak ister misiniz?

Benim çözümümü görmek için 

Ben öncelikle http://www.hcidata.info/host2ip.cgi adresindeki formu inceleyerek başladım;

YoutubeHostDuzenleyici_1

WebRequest sınıfından bir örnek oluşturdum, sayfanın çıktısını GetResponse() methodu ile alarak WebResponse sınıfında bir nesnede sakladım. StreamReader nesnesini kullarak, sayfanın HTML çıktısını string tipinde bir değişkene atadım.

v{1-24}.lscache{1-8}.c.youtube.com adreslerinin ip adreslerini bulmak için içiçe iki paralel for döngüsü kurdum.

response değişkeninde oluşan HTML’i parse ederek, ip adresine ulaştım.

hosts dosyasında youtube.com adresli satırları bulmak ve güncellemek için .Net Regular Expression (Regex) classını kullandım.

Son olarak, bu kodları fonksiyon haline getirdim;

private void btnIPBul_Click(object sender, EventArgs e) { txtHosts.Clear(); StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format(“{0}\t{1}”, FindIP(“youtube.com”), “youtube.com”)); sb.AppendLine(string.Format(“{0}\t{1}”, FindIP(“www.youtube.com”), “www.youtube.com”)); sb.AppendLine(string.Format(“{0}\t{1}”, FindIP(“img.youtube.com”), “img.youtube.com”)); Parallel.For(1, 9, iLoop => { Parallel.For(1, 25, yLoop => { string url = string.Format(“v{0}.lscache{1}.c.youtube.com”, yLoop, iLoop); sb.AppendLine(string.Format(“{0}\t{1}”, FindIP(url), url)); }); });

txtHosts.Text = sb.ToString(); }

private string FindIP(string AddressToLookUp) { WebRequest r = WebRequest.Create(string.Format(“http://www.hcidata.info/host2ip.cgi?domainname={0}&findIP=Find IP Address&ipaddress=127.0.0.1”, AddressToLookUp)); WebResponse s = r.GetResponse();

StreamReader sr = new StreamReader(s.GetResponseStream(), Encoding.UTF8);
string response = sr.ReadToEnd();

sr.Close();
s.Close();

string ipAddress = response.Substring(response.IndexOf("IP Address : ") + 13, 16);

return ipAddress.Substring(0, ipAddress.IndexOf("\n")); }

private void btnHostsGuncelle_Click(object sender, EventArgs e) { if (txtHosts.Text == “”) btnIPBul.PerformClick();

Regex r = new Regex(@"^(.*youtube\.com)");
StringBuilder sb = new StringBuilder();

foreach (string line in File.ReadAllText(@"C:\Windows\System32\drivers\etc\hosts").Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
    if (!r.IsMatch(line))
        sb.AppendLine(line);

sb.AppendLine();
sb.AppendLine();
sb.AppendLine("# youtube.com IP'leri Buradan Başlıyor");
sb.Append(txtHosts.Text);

File.WriteAllText(@"C:\Windows\System32\drivers\etc\hosts", sb.ToString()); }

Uygulamanın kodlarını buradan indirebilirsiniz.

VB.NET'te anahtar kelimeyi değişken ismi olarak kullanma

Daha önce yazdığım C#’ta anahtar kelimeyi değişken ismi olarak kullanma yazımda, aynı işin VB.NET’te nasıl yapılacağını yazmamıştım.

Değişken isminin, dilin anahtar kelimelerinden biri olmasına verbatim identifier deniyor.

MSDN’de C# dili için verbatim identifier nasıl tanımlanır makalesi mevcut, fakat VB.NET için nasıl yapılacağı dökümante edilmemiş.

Hala verbatim identifier tanımlamanın KÖTÜ bir fikir olduğunu düşünüyorum, fakat VB.NET’te verbatim identifier nasıl tanımlanır, merak edenler için;

Dim [String] As String = “” Dim [For] As Boolean = True Dim [While] As Integer = 6 Dim [False] As DateTime = DateTime.Now Dim [ReadOnly] As File

Kısa Sınav - 9

Sql Server’da veritabanında zaten varolan bir tabloya yeni bir alan eklemek istiyorsunuz. Yeni ekleyeceğiniz alanda, PersonelNo bilgisini saklayacaksınız.

PersonelNo bilgisi herzaman 5 karakterden oluşuyor. Dünya üzerinde çeşitli ülkelerde çalışan yüzlerce çalışanınız olduğu için, PersonelNo alanında saklayacağınız bilgiler genelde Unicode karakterlerden oluşuyor.

PersonelNo alanı için en uygun veritipi ne olmalı?

  • nvarchar(5)
  • varchar(50)
  • nchar(5)
  • char(5) Sorunun doğru cevabı için; Doğru cevap: nchar(5)

nchar veritipi sabit-uzunluklu unicode veri saklayabilir. Sorudaki ihtiyaçlar için, nchar(5) veritipini seçmek en mantıklısı olacaktır.

varchar veritipi değişken-uzunluklu metin bilgisi saklayabilir. Sorudaki ihtiyaç, sabit uzunluk (5) olduğu için, bu veritipini seçmek gereksizdir.

nvarchar veritipi değişken-uzunluklu unicode veri saklayabilir. Sorudaki ihtiyaç, sabit uzunluk (5) olduğu için, bu veritipini de seçmemeliyiz.

char veritipi unicode veri saklayamaz.

.Net Framework'te Timer Class'ları Arasındaki Farklar

BilgeAdam’da öğrencilerime WinForms anlatırken, kafalarının çok karıştığı konulardan biri de Timer nesnesidir.

Daha doğrusu Timer nesneleridir demeliyim. Çünkü .Net Framework’te Timer ismine sahip tam 3 tane class var;

Özellikle Multi-Threaded uygulamalarda tercih edilir. Thread-safe olduğu için, birden çok thread’den erişilebilir.

System.Timers.Timer t = new System.Timers.Timer(5000); t.Elapsed += delegate(object _s, System.Timers.ElapsedEventArgs _e) { MessageBox.Show(“5 saniye geçti!..”); t.Stop(); }; t.Start();</pre> System.Threading.Timer

TimerCallBack delegate kullanarak, atanmış metodu çalıştırabilir. Metod, framework tarafından oluşturulan başka bir thread’de çalışır.

Timer nesnesi oluşturulduğu anda, çalışmaya başlar ve scope’tan çıkana kadar da çalışır. Durdurmak veya Başlatmak mümkün değildir.

Aşağıdaki örnekte 2.parametre (null), Callback method’a aktarılacak parametreyi gösterir.

3.parametre (1000), Timer nesnesi başlatılmadan önce beklenecek süreyi gösterir.

System.Threading.Timer t = new System.Threading.Timer(new System.Threading.TimerCallback(TimerTest), null, 1000, 5000);
private void TimerTest(object state)
{
    MessageBox.Show("5 saniye geçti!..");
}

System.Windows.Forms.Timer

Toolbox’ta gördüğümüz nesnedir. Windows Form ile aynı thread’de ve senkron olarak çalışır, böylece hiçbir UI operasyonunu bölmez.

System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 5000;
t.Start();
t.Tick += delegate(object _s, EventArgs _e)
{
    MessageBox.Show("5 saniye geçti!..");
    t.Stop();
};

Daha ayrıntılı bilgi için MSDN'deki şu makaleyi okuyabilirsiniz.

Engin Polat hakkında

Chief Architect, Microsoft RD, Microsoft MVP

Ada ve Ege'nin babası ;)

Kategoriler

İstatistik

Makale Adedi: 458

Creative Commons Lisansı