Duyuruyu Kapat
Facebook Gözat
Twitter Gözat

Tüm Dosyaları MD5'lemek! (hızlı çözüm)

Konu, 'D Dili' kısmında Salih Dinçer tarafından paylaşıldı.

  1. Salih Dinçer

    Salih Dinçer Üye

    Kayıt:
    24 Şubat 2012
    Mesajlar:
    53
    Beğenilen Mesajlar:
    0
    Merhaba,

    Herhalde bilimsel amaçlı kullanımları olsa gerek ama bizler sıklıkla MD5 gibi algoritmalarını dosya doğrulamada kullanıyoruz; belki de en çok DAT, ISO, IMG gibi büyük DVD dosyalarını doğrulamada...

    Elbette yayıncısının verdiği tam MD5 kodu ile uyuşmaz ama büyük dosyaları bu algoritmadan geçirmek çok vakit alabiliyor. Bunu hızlıca yapmak için dosyadaki tüm verileri değil de küçük bir kısmını seçebiliriz. Örneğin ikiz asallardan oluşan bir diziyi...

    Aşağıda, bunu D ile kolayca yapılabileceğini göreceksiniz. Aslında böyle bir yazılım yazmaya niyetim yoktu. Özellikle şuradaki tartışma için yazdığım kodu kullanabileceğimi düşündüm: http://forum.ceviz.net/c-c/121372-konuyu-nereye-acacagimi-bilemedim-crclist-hakkinda.html#post711565

    Evet, artık yeni bir D kategorimiz olduğuna göre özgürce bu dili konuşalım. Örneğin merak ettiğiniz satırları cevaplayabilirim...

    Kod:
    /*
     *   fileMD5.d(08.10.2012)
     */
    import std.stdio, std.conv, std.file, std.md5;
    
    struct dosyaTaşıyıcısı {
        char[1024] verisi;
    
        auto bulGetir() {
            size_t[] asal = [ 3, 5, 11, 17, 29, 41, 59, 71, 101,
                              107, 137, 149, 179, 191, 197, 227,
                              239, 269, 281, 311, 347, 419, 431, //];/* toogleCode
                              461, 521, 569, 599, 617, 641, 659,
                              809, 821, 827, 857, 881, 1019 ];//*/
            char[][] seç;
    
    
            foreach(x; asal) {
                if(x < verisi.length) {
                    seç ~= [ verisi[x..x+1], verisi[x+2..x+3] ];
                }
            }
            return to!string(seç);
        }
    }
    
    void main(string[] args) {
        string dizin = ".\\";
        version (linux) dizin = "./";
        string dosyaYolu = args.length > 1 ? args[1] : dizin;
        auto dosyaAdı = listDir(dosyaYolu);
        auto dosya = new dosyaTaşıyıcısı[dosyaAdı.length];
        
        foreach(sırası, adı; dosyaAdı) {
            with(dosya[sırası]) {
                if( ! isDir(adı) ) {
                    auto oku = File(dosyaYolu ~ adı, "r");
                    oku.rawRead(verisi);
                    bulGetir.getDigestString.writeln;
                }
            }
        }
    }
    KULLANIMI:
    - dmd fileMD5.d -release komutu ile derleyip
    - fileMD5 ./falanca_dizin/
    diye çalıştırırsanız, o dizin içindeki tüm dosyaların hızlıca MD5 kodunu ekrana yazar. Dilerseniz şu şekilde bunları bir dosyaya da yazabilirsiniz: fileMD5 > md5ler.txt (Bu örnek parametre almadığı için bulunduğu dizine MD5'ler)

    Dip Not:
    Bu kodun çok eksiği var. Hatta listDir() işlevi yakında "deprecated" olacakmış. Yine de biri yapı içinde diğeri main() işlevinde olmak üzere iki tane if() koşulu sayesinde hata kontrolü sağladım. Dilerseniz toggleCode satırını etkinleştirip hızlandırabilirsiniz de. Dizideki elemanların daha da az olması önerilmez. Özellike obj dosyalarında hep aynı MD5 kodu üretebilir.

    Başarılar...
     
  2. Salih Dinçer

    Salih Dinçer Üye

    Kayıt:
    24 Şubat 2012
    Mesajlar:
    53
    Beğenilen Mesajlar:
    0
    Dün akşam fazla vakit bulamamıştım ama kodda bir kaç hata varmış. Özellikle fileMD5 ./dizin/ şeklinde kullanımını etkiliyordu. Çünkü isDir() işlevi "full path" istiyormuş. İletimi düzenleyemediğim için aşağıya 0.9 sürümünü (ingilzcesini) aşağıya naklediyorum:
    Kod:
    /* *   genMD5files.d (v0.9)
     */
    import std.stdio, std.conv, std.file, std.md5;
    
    
    class container {
        char[1024] buffer;
    
    
        override string toString() {
            int[] primes = [ 3, 5, 11, 17, 29, 41, 59, 71, 101,
                             107, 137, 149, 179, 191, 197, 227,
                             239, 269, 281, 311, 347, 419, 431,
                             461, 521, 569, 599, 617, 641, 659,
                             809, 821, 827, 857, 881, 1019 ];
            char[][] md5;
    
    
            foreach(x; primes) {
                if(x < buffer.length) {
                    md5 ~= [ buffer[x..x+1], buffer[x+2..x+3] ];
                }
            }
            return getDigestString(to!string(md5));
        }
    }
    
    
    void main(string[] args) {
        string root = ".\\";
        version (linux) root = "./";
        string path = args.length > 1 ? args[1] : root;
    
    
        foreach(name; listDir(path)) {
            auto full_name = path ~ name;
            with(new container) {
                if( ! isDir(name) ) {
                    auto data = File(name, "r");
                    data.rawRead(buffer);
                    toString.writeln(" (", name, ")");
                }
            }
        }
    }
    Bir de özyinelemeli tüm dosyaları tarayan 1.1 sürümü var: http://ddili.org/forum/thread/995