Mega Code Archive

 
Categories / Delphi / Forum
 

Neoturk - coder testi

Herkese merhaba, Hazırlamış olduğum soruların cevaplarını yayınlıyorum. Bu arada hiç kimseden de "Coderlik" öğrenme çabası gelmediğini farkettim. Programcılıkla uğraşacan kişi sayısı ya çok az, ya da ilgi gösterilmiyor bu konu üzerine diye düşünüyorum... Sonuç olarak, yine sözümüzde durarak cevapları "hayırlı uğurlu olsun, yeni çekirgeler yetişsin bizi geçsin" diyerekten yayınlıyorum. Hepinize başarılar, iyi çalışmalar diliyorum... Kalın sağlıcakla.. SORU 1: Aşağıdaki kodu YORUMLAYINIZ ( 10 puan ) (10) function topla; var a:variant;b:variant; begin a:=5;b:=10; sonuc=a*b; end; CEVAP: Yukardaki function gereksiz yere tanımlanmış bir function. Çünkü "topla" adlı functionun "result" değeri herhangi bir değere atanmamış. "sonuc" adlı değişken "global" olarak tanımlanmış ise şayet, böyle bir function yazmanın herhangi bir mantığa veya akla hizmet etmesi beklenemez.. gereksiz function yazımı olur... ayrıca, variant tipli değişken kullanmaya da gerek yok.. ayrıca 5x10 işlemi için bu functionu hazırlamaya da gerek yok.. tamamiyle yazılmış olmak için yazılmış bir gereksiz function.. herhangi bir akla veya mantığa hizmet etmiyor.... SORU 2: Aşağıdaki kodu YORUMLAYINIZ ( 10 puan ) (20) prodecure sayac; var a:integer;b:integer; begin a:=0;b:=0; repeat a:=a+1; form1.label1.caption:=inttostr(a); until a=1000; repeat inc(b); form1.label2.caption:=inttostr(b); until b=1000; end; CEVAP: Procedurde herhangi bir syntax hatası görünmüyor ilk etapda. mantıken akıldan çalıştırdığımızda da doğru çalıştığını görürüz. yapılmak istenen "olay"ı uzatarak yapmak istemiş vatandaş.. form1 üzerinde bulunan label1 ve label2 etiketleri üzerine 1 den 1000e kadar olan sayılar yazdırılmak istenmiş. ancak, burada yine de zayıf kodlama görüyoruz.. Burada bilinmesi gereken, etiketler üzerinde seri işlem yaptırılırken "label1.refresh" tazeleme'nin kullanılmasının gerektiği ( yoksa ekranda donarak kalır ) veya application.progressmessages apisi ile diğer işlemlere de izin verilmesi gerektiği. Döngüleri gereksiz yere "repeat-until" ile uzatmaya gerek yok. basit bir "for-do" döngüsü ile de yapılabilir... Ayrıca yapılmak istenen önce label1'e sayıları yazdırmak, daha sonra label2'ye sayıları yazdırmak. Bu, coderin seçimi olmuş burada.. Procedurun geneline bakıldığında yine gereksiz işlemler bütünlüğü olarak gördüğümüz için, tüm bu yapılan işlemleri tek bir "for-do" döngüsünde 2 tane labele aynı anda işlemimizi daha kolay yaptırabilirdik.. şu şekilde: procedure sayac; var a:integer; begin for a:=1 to 1000 do begin form1.label1.caption:=inttostr(a);form1.label1.refresh; form1.label2.caption:=inttostr(b);form1.label2.refresh; application.progressmessages; end; aynı işi yapar.. daha sağlıklı ve daha basit bir kodlama.. ( b değişkenini de çöpe attık,hafızadan tasarruf.. İnce düşünmek gerekiyor her zaman! ) SORU 3: Aşağıdaki kodu YORUMLAYINIZ ( 50 puan ) (70) procedure islemyap; var a,b:integer; s:string; d:olevariant; begin for x:=1 to 1000 do form1.memo1.lines.add('merhaba'); form1.caption:=inttostr(x); end; if s='neo' then exit; end; CEVAP: Öncelikle, çok gereksiz bir procedure olduğunu görüyoruz.. mantığın tam oturmamış ve yapılmak isteneni koda yansıtamamış bir uğraş olduğunu görüyoruz... syntax yazım hatası yok, ama mantıksız bir çok işlev var.. Yapılan mantıksal hataları sıralayalım: 1. "s" değeri parametre olmadığına göre bu değer hiç bir zaman "neo" değerini almayacağı için "exit" deyimi yerine getirilemeyecektir. 2. Hadi diyelim ki procedure içinde "s" değerine "neo" değerini atadık, son satıra gelinmiş olduğu halde neden "exit" ile procedurden çıkılmak istensin ?... ( mantıksızlık ) 3. a,b ve d değişkenleri tanımlanmış ama hiç bir yerde kullanılmamış.. gereksiz yere hafızadan yer ayırtılmış.. kodu da kalabalıklaştırmaktan başka bir işe yaramıyor... 4. döngüde "x" değeri kullanılmış ama "x" değeri tanıtılmamış.... hata verip çalışmayacaktır program.. ( mantıksal hata ) procedurde yapılmak istenen olaya baktığımızda, form başlığına 1den 1000e kadar sayıları yazdırmak ve bu arada memo nesnesi içerisine 1000 adet "merhaba" yazısını eklemek... SORU 4: Aşağıdaki kodu YORUMLAYINIZ ( 50 puan ) (120) procedure islem; var m:integer; begin for m:=1 to 10 do form1.memo1.lines.add('process1'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process2'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process3'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process4'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process5'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process6'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process7'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process8'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process9'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process10'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process11'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process12'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process13'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process14'+inttostr(m); for m:=1 to 10 do form1.memo1.lines.add('process15'+inttostr(m); end; CEVAP: Mantıksal veya syntax hatası yok.. yapılmak istenene baktığımızda form1 üzerindeki memo nesnesi üzerine seri olarak "process" yazılarının yanına 1den 10a kadar sayıları yazdırmak olduğunu görüyoruz.. Burada kod uzatılarak yazılmış.. daha kısa yazılabilirdi.. yeni başlayan programcıların sıkça yaptığı bir yazım reaksiyonudur bu şekilde kodlamak.. hemen hemen tüm yeni programcılarda bu türden kodlarla uzun uzadıya kodlamanın yapıldığını görürsünüz... ( deneyimliler için söylüyorum ) Daha da kısaltılmış olanı şu şekilde yazardım ben olsaydım: procedure islem; var m,n:integer; begin for n:=1 to 15 do for m:=1 to 10 do form1.memo1.lines.add('process'+inttostr(n)+inttostr(m); end; bu kadar basit.... SORU 5: Ekrana kursör(imleç) kullanıyormuş gibi yazı yazdıran bir function yazınız? ( 50 puan - süreniz 1 dakika ) (170) ben bir coderim_ ( her harften sonra imleç görüntüleniyor olacak ) CEVAP: Burada bizden istenen olay, 1 dakika içersinde mantığımızı hızlıca koda yansıtabilmek.. asıl istenen olay bu.. deneyimli bir programcı istenenin ne olduğuna o kadar önem vermez, bizden istenileni o anda "nasıl kodlarım?" sorusunu kendisine sorar ve mantığını hemen oluşturur.. Bilgili ve deneyimli olmak hızı beraberinde getirir... tecrübesiz bir programcı uzun sürede mantık kurar.. 2saatte yazar... bu da en kızdığım olaylardan birisidir... yazamamak hata değil, "geç yazmak hata" diye düşünüyorum... çünkü bilgisi olsaydı istenileni hemen koda dökebilirdi.. kısa zaman zarfında koda dökemiyorsa tecrübe ve deneyimi yetersiz anlamına geliyor... procedure ekranayaz(var x:string); var m,n:integer; begin n:=length(x); for m:=1 to n do begin form1.label1.caption:=copy(x,1,m);form1.label1.refresh;sleep(10); form1.label1.caption:=copy(x,1,m)+chr(219);form1.label1.refresh;sleep(10); end; button1.onclick olayına şunu yazabiliriz: begin ekranayaz('ben bir coderim'); end; form1 üzerindeki label1 üzerine yazar. ( form.canvas ile de yapılabilirdi ama bu şekilde kullanmak daha etkin ve basit.. ayrıca 219 karakter kodunun içi dolu dikdörtgen kursor olduğunu deneyimli olanlar bilirler. ve böyle bir kursoru da kullanabilmeniz için yazı fontunuzun "terminal" olması gerekmektedir....... bitti...... SORU 6: Aşağıdaki kodu YORUMLAYINIZ ? ( 100 puan ) (270) serversocket1.socket.connections[1].sendtext('neoturk1'); serversocket1.socket.connections[1].sendtext('neoturk2'); serversocket1.socket.connections[1].sendtext('neoturk3'); serversocket1.socket.sendtext('neoturk1'); serversocket1.socket.sendtext('neoturk2'); serversocket1.socket.sendtext('neoturk3'); for m:=1 to 10 do begin serversocket1.socket.sendtext('neoturk'+inttostr(m)); end; CEVAP: evet... güzel bir soru... konumuz winsock... syntax hatası yok.. mantık hatası da yok.. sadece dikkat ve deneyim gerektiriyor.. yukarıda bahsi geçen satırlar tüm socket programlarında kullanılan temel satırlardan birisidir.. Yukardaki satırları aynı procedure içinde kullanmaya kalksaydık farklı tepkiler alabilirdik.. çünkü aynı bağlantıya 3 adet stringi göndermenin akibetinin ne olacağını meçhul?!.. hepsi karşı tarafa ulaşabilir de.. ulaşmaya bilir de... bunun için "block" ve "none-block" konusunun hemen belleklerimizden tazelenmesi gerekiyor.. ard arda stringsel veriler gönderileceği zaman "block socket" kullanmamız gerekiyor.. iş kuyruğu mantığı yani.. ama varsayılan ayarlar genelde "none-block" olduğu için bir çoğu burada "çuvallar".... aynı şekilde "connections[1]" ifadesi ile "socket.sendtext" ifadesi arasındaki farka dikkatiniz çekmiş olmalı... connections[1] ifadesi ile "2" nolu bağlantı sahibine mesaj attırmak isteniyorken, "socket.sendtext" ifadesi ile o anda aktif olan socket bağlantısına "socket handle" mesaj atılmak isteniyor.. hemen aşağısındaki döngü olayında da 10 kere "neoturkX" serisi gönderiliyor.. ve aktif olan socket bağlantısına.. bu konu biraz geniş.. uzun uzadıya yazmak istemiyorum şu an için.. Kitaplardan okuyarak kendinizi daha fazla geliştirmenizi tavsiye ederim... ve bu türden fazlasıyla uygulama yazıp üzerinde değişik deneyler yaparak farkları öğrenebilirsiniz... SORU 7: Aşağıdaki kodu YORUMLAYINIZ ( 100 puan ) (370) ... function RegisterServiceProcess (dwProcessID, dwType: DWord) : DWord; stdcall; external 'KERNEL32.DLL'; implementation uses unit2; ... CEVAP: Belki yeri değil ama, trojan programcılığıyla ilgilenenler yukardaki functionun ne işe yaradığını hemen anlayacaklardır. Yukardaki function "kernel32.dll" kitaplığını kullanarak windows9x işletim sistemlerinde uygulamayı "ctrl+alt+del" den saklamak için hazırlanmış. önce kaynak belirtiliyor.. kullanılan komut ise program içersinde yeri geldiğinde belirtilecek.. Ve hemen şunu da belirtmek istiyorum, yukardaki kodu gören deneyimli bir programcı hemen şunu şöyleyebilirdi: "bu program Windowx2000 veya XP de çalışmaz!" evet doğrudur... bu da tecrübeden kaynaklanıyor.... çünkü windows9x kernel32.dll ile windowsNT kernel32 si arasında farklılıklar var. Buna da çekirdek mimarisi eşlik ediyor zaten ya!.. boşuna ayrı ayrı yazılmıyor programlar değil mi?.... SORU 8: masaüstü duvar kağıdı resminin değiştirilmesi isteniyor, coder arkadaşımız aşağıdaki şekilde bir kod kullanmış, kodu yorumlayınız ? ( 100 puan ) (470) var s:string; begin s:='c:\deneme.bmp'; systemparametersinfo(SPI_SETDESKWALLPAPER,0,PCHAR(S),0); end; CEVAP: Eveett.. Çok şirin bir kod. Ama yemez bu! :) Neden yemediğini da izah edeyim, ilgili bitmap resmini windowsa belirtiyor, ve systemparametersinfo apisi ile de windows bunu masaüstü duvar kağıdı diye kendisini ayarlara yerleştiriliyor. ama ekranı refresh yapmıyor haliyle ( F5 olan refresh değil! ) procedure Tneoturk.SetWallpaper(sender:Tobject;sWallPaperBMPPath: string; bTile: Boolean); var reg: TRegIniFile; begin reg := TRegIniFile.Create('Control Panel\Desktop'); try with reg do begin WriteString('', 'Wallpaper', sWallPaperBMPPath); WriteString('', 'TileWallpaper', IntToStr(Ord(bTile))); end; finally reg.Free; end; SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE); end; Bu kod ile bahsettiğim gibi manuel olarak elle masaüstü duvar kağıdı ayarlara işleniyor ( HKLM anahtarındaki control panel\desktop anahtarına ) ( incelemenizi tavsiye ederim ) ve ardından sistem apisi ile refresh yapılıyor... SORU 9: C sınıfı bir adres alanı alınmış olsun. Ağ yöneticisi bu adres alanını şirkette bulunan 6 bölüme bölerek alt ağlar oluşturmak istemektedir. buna göre herbir altağ için altağ adresleri, ağ maskesi ve altağların yayın adresleri ne olur ? ( Alınan C sınıfı adress 199.6.13.0'dır. ) ( 100 puan ) (570) CEVAP: C sınıfı adresin ağ maskesi 255.255.255.0'dır. 6 altağ elde edebilmek için sistem için ayrılan bitlerden 3 bit (2^3=8) ödünç alınır ve burası altağ adreslemesi için kullanılır. dolayısıyla bir C sınıfı adreste 24 bit olan ağ adres kısmı 3 bit daha eklenerek 27 bite çıkmış olur. Buna göre; C sınıfı adres -> 199.6.13.0 Ağ maskesi -> 255.255.255.0 Altağ adresleri: 0.altağ = 199.6.13.0 1.altağ = 199.6.13.32 2.altağ = 199.6.13.64 3.altağ = 199.6.13.96 4.altağ = 199.6.13.128 5.altağ = 199.6.13.160 6.altağ = 199.6.13.192 7.altağ = 199.6.13.224 Yeni alt ağların maskeleri hepsi için aynı olup 225.255.255.255 olur. Altağlar içerisindeki sistemlerin adresleri en sağda kalan 5 bitlik sayılarından bulunur. Örneğin, 199.6.13.0 adresli altağ içindeki sistem adresler, 199.6.13.1 199.6.13.2 199.6.13.3 olur. Benzer şekilde 199.6.13.32 adresli ikinci altağ içindeki sistemlere de sırasıyla 199.6.13.33,..62,63 verilebilir. Altağlara ait yayın adresleri, altağ içerisindeki sistemleri adresleyen 5 bitin hepsinin 1 yapılmasıyla bulunur. Örneğin 199.6.13.32 alt ağı için yayın adresi şöyle hesaplanır. ağ adresi = 199.6.13.32 32 sayısı = 0 0 1 0 0 0 0 0 -> 0 0 1 1 1 1 1 1 => 63 199.6.13.32 altağın yayın adresi 199.6.13.63 olarak bulunur. 199.6.13.64 altağı için yayın adresi 199.6.13.95'dir... (kaynak: tcp/ip unix el kitabı ) SORU 10: Aşağıdaki kodu YORUMLAYINIZ ? ( 100 puan ) (670) procedure Tform1.parcala(sender:Tobject;x:string); var account,m,n:integer;x2:string; begin for m:=1 to 6 do xitem[m]:=''; account:=1; x2:=''; n:=length(x); for m:=1 to n do begin if x[m]='_' then begin xitem[account]:=x2; x2:=''; inc(account); end else begin x2:=x2+x[m]; end; end; xitem[account]:=x2; end; CEVAP: Evet... Herhangi bir mantıksal hata veya syntax hatası yok... Bu procedurun yapmak istediği olay şudur: "ben_bir_coderim" stringini parametre olarak gönderdiğimizde bize sonuç olarak xitem[1]:=ben xitem[2]:=bir xitem[3]:=coderim xitem[4]:= xitem[5]:= xitem[6]:= sonucu döndürür... xitem array string olarak "global" olarak tanıtılmış olması gerektirir.. çünkü procedure içinde bu array tanıtılmamış. demek ki global olarak mutlaka tanıtılmıştır... aynı şekilde bu procedure, faydalı birer tool olarak geliştirilebilir.. özellikle parametrik stringler gönderildiğinde bunları parametrelere ayırmak istenildiğinde kullanılabilir... ( ben bunu kullanmıştım örneğin ) aynı şekilde kodda oynama yapılarak daha farklı varyasyonlar da yapılabilir. ve 6 item sayısı da artırılabilir.. daha da etkinleştirilebilir.. "ben*bir*coderim*delphiyi*cok*seviyorum*cok*calismaliyiz" stringini gönderdiğimizde ( procedurdeki "_" simgesini "*" olarak değiştirmemiz gerekiyor, gözünüzden kaçmasın! ) xitem[1]:=ben xitem[2]:=bir xitem[3]:=coderim xitem[4]:=delphiyi xitem[5]:=cok xitem[6]:=seviyorum sonucunu döndürür.... özellikle dediğim gibi stringi parametrelerine parçalamada kullanılabilir... benim epey işime yaramıştı... SORU 11: Yazdığınız bir uygulamayı kendi kendine yeniden restart ettirmek istiyorsunuz ve bunu da defalarca tekrarlamasını istiyorsunuz, aynı anda 2 programın çalışması istenmemektedir.. Bunu hangi kodla ve ne tür bir mantıkla yaparsınız ? ( kodun kısa olması istenmektedir ) ( 100 puan ) (770) CEVAP: evet.. Bunun genelde uzun yöntemleri vardır.. ama bizden istenen kısa bir yöntem?... ilk akla gelen şu kod işimizi halledecektir: application.terminate; sleep(1000); winexec(pchar(application.exename),1); halt; finito!.. SORU 12: Herhangi bir klasör içerisindeki tüm text dosyalarının sadece birinci satırlarının okutulması ve bu okunan satırların başka bir text dosyasında toparlanması istenmektedir. İlgili kodu yazınız. ( 150 puan ) (920) CEVAP: evet.. can sıkıcı bi durum.. sadece hamallık yapacaz biraz! :) Öncelikle formumuza bir adet directorylistbox ve filelistbox ( ilişkili ) yerleştirelim. button1 olayına da "toparla" diyip hemen kodlamaya başlayalım ( pcmin başında olsaydınız görürdünüz :=)) ) kafadan teorik kodluyorum, gözümüzle çalıştırıyoruz... button1.onclick olayı: var fblock,totallist:Tstringlist; m,n:integer;x:string; begin n:=filelistbox1.count-1; //tüm dosya sayısını al ( hangi klasördeysen artık ) fblock:=Tstringlist.create; totallist:=Tstringlist.create; // olay bitmiştir.. şimdiden finito! for m:=0 to n do //döngüyü aç bakalım begin x:=filelistbox1.items[m]; fblock.loadfromfile(directorylistbox1.directory+'\'+x); //dosyayı yükledinmi kardeş?.. x:=fblock.strings[0];//yüklediğin dosyadan 1.satırı oku.. ( x değişkeniyle 1 taşla 2 kuş vuruyoruz ) totallist.add(x);//hop sepete at!.. end; //devammm //final totallist.savetofile('c:\totallist.txt'); winexec('c:\totallist.txt',1);//notepadde aç kardeşim.. totallist.free;//boşalt fblock.free;//boşalt end; teorik olarak bu şekilde yazdık.. çalışır heralde ? :=)) çalışır çalışır... sorun diil..... Bunu daha da geliştirip "function" haline de getirebiliriz... "target folder" filan... anlarsınız :=) SORU 13: Aşağıdaki kodu YORUMLAYINIZ ? ( 150 puan ) (1070) procedure regtoparla; var m,n,m2,n2:integer; x3:char; x,x2:string; begin tempx.Clear; n:=regtools.listbox2.Items.count-1; for m:=0 to n do tempx.add(regtools.listbox2.items[m]); if n<0 then tempx.add(''); tempx.add('&&&'); n:=regtools.listbox3.Items.count-1; for m:=0 to n do begin x:=regtools.listbox3.items[m]; n2:=length(x); x2:=''; for m2:=1 to n2 do begin x3:=x[m2]; case x3 of #10,#13:x3:='?'; end;//case x2:=x2+x3; end; tempx.add(x2); end; //if n<0 then tempx.add(''); tempx.add('&&&'); n:=regtools.listbox4.Items.count-1; for m:=0 to n do begin x:=regtools.listbox4.items[m]; n2:=length(x); x2:=''; for m2:=1 to n2 do begin x3:=x[m2]; case x3 of #10,#13:x3:='?'; end;//case x2:=x2+x3; end; tempx.add(x2); end; //if n<0 then tempx.add(''); tempx.add('&&&'); x:=regtools.label1.caption; tempx.add(x); end; CEVAP: hmm.. bu kodu neoturk1.0-1.3 versiyonlarında kullanmıştım.. şu işe yarıyor bu kod: ilgili bir registry anahtarındaki tüm data ve value değerlerini alt alta biriktiriyor. Blocklar arasına ayraç olsun diye "&&&" simgesini yerleştiriyorum... daha sonra bunu text formatına kaydedip cliente gönderiyorum. client de bunları tekrar geri yerine basıyor ve karşı tarafın registry penceresini kullanıyormuş gibi oluyoruz... biraz uzun hikaye.. ama yaptığı iş bu... regtoparla dememin sebebi ilgili aktif anahtar neyse o anahtardaki tüm data ve valueleri tek bir "tempx" bloğunda toparlıyor olması.. oldukça işime yaramıştı... nostalji işte.. :) SORU 14: Çalışan bir uygulamanın kapatılması isteniyor, aşağıdaki kodlama bu iş için uygun mudur ? neden ? ( 200 puan ) (1270) msg:=listbox1.items[listbox1.itemindex]; wndhandle := FindWindow(nil,pchar(msg)); if wndhandle <> 0 then PostMessage(wndhandle,WM_CLOSE,0,0); CEVAP: Burada deneyimli bir coder hemen deneyimini konuşturup "hayır uygun değildir!" der!.. Olayın hikayesi basit. Teorik olarak açıklayayım: "Findwindow" olayını hemen hemen tüm coderler bilirler.. ve ilginçtir bir çok open source'da bu tip ibareler kullanılır.. ama çok fazla etkin değildir bu kod.. nedenine gelince, findwindow apisi, ekranda var olan açık pencereler üzerinde işlem yaparlar. ve bazı uygulamaların da 1den fazla penceresi vardır. ve siz bir alt pencereyi kapatırsanız o alt pencereyi bu kod kapatır. ama uygulamayı kapatmaz!.. uygulamayı kapatmak istiyorsanız uygulamaya ait pencerenin tam adını bulmanız gerekmektedir ( vatandaşımız listede seçili olan pencere başlığını kapattığını varsayıyor kodunda ) Bu yüzden findwindow ile uygulama kapatılma olayı her zaman geçerli değildir.. şayet uygulamayı kapatmak istiyorsanız "killtask exe" procedurlerini oluşturmanız gerekmektedir. yani çalışan exe uygulamalarını "kill" etmelisiniz... findwindow ile değil!.. Tabii burada bu konuda benden daha deneyimli olan dostum Atmaca'nın da fikirlerini sizlere arz etmek isterdim.. Onun geliştirmiş olduğu "görünmez exe" olayını ben şu an için bilmiyorum... e durum böyle olunca da görünmeyen bir uygulamayı nasıl kill edebileceğim konusunda ona danışmakta fayda görüyorum! Bu konuda Atmaca'dan daha detaylı bilgi istemeniz mümkün.. ancak böyle önemli bir bilgiyi istemeniz için o bilgiyi hak ediyor olmalısınız!! "Altından Sarraf anlar" dememişler boşuna değil mi?.. SORU 15: Sıra ile üretilmek üzere tasarlanmış şifreler vardır. Basit bir döngü ile bu işlem yapılabilir. örnek aşağıda olduğu gibidir: ... key:='ABCD'; for m1:=1 to 4 do for m2:=1 to 4 do for m3:=1 to 4 do for m4:=1 to 4 do begin X:=key[m1]+key[m2]+key[m3]+key[m4]; memo1.lines.add(x); end; ... bu kodun çıktısı aşağıdaki gibi olacaktır; AAAA AAAB AAAC AAAD AABA AABB AABC ... DDDC DDDD bunların başına numara imi ekleyecek olur isek, 1-AAAA 2-AAAB 3-AAAC 4-AAAD 5-AABA 6-AABB 7-AABC ... 255-DDDC 256-DDDD olduğunu görürüz... key='ABCDEFGHIJKLMNOPRSTUVYZQWX' olarak değiştirmek isteyelim.. ve 8 haneli şifreleri aynı şekilde ürettiğimizi varsayalım.. (bunun için 8 döngü açtığımızı varsayıyoruz ) 1-AAAAAAAA 2-AAAAAAAB 3-AAAAAAAC ..... bu şekilde üretilmiş seri şifreler arasında 123.456.780'nci sıradaki şifrenin ne olacağını söyleyiniz ? ( 250 puan ) (1520) CEVAP: Bu yöntemi "brute force ( kaba üstün körü atak )" tekniği için geliştirmiştim.. henüz deneme şerefine nail olmadım ama bir gün deneyecem merak etmeyin :) yani bu konu ile ilgili herhangi bir program yazmadım.. ama yazacağım, emin olabilirsiniz... yazmasına yazacağım ama bu konuda epeyce bir araştırma yaptım ve şöyle bir sonuç elde ettim okuduğum ve toparladığım bilgiler sayesinde: "16 haneli bir şifrenin brute force ile kırılabilmesi için toplam olarak bilmem kaç KATRILYON sene geçmesi gerekiyormuş. Sn'de 100Trilyon şifre denendiği varsayılıyor... ) bende yazmaktan vazgeçtim... sadece teoride araştırma "kriptografi" olarak kaldı... Bu konudaki sonuçları açıklayayım: şifrenin ilgili hane sayısında olması durumunda deneme yanılma yapılması gereken miktar sayısı: ----------------------- Key =ABCDEFGHIJKLMNOPRSTUVYZQWX ----------------------- Key uzunluğu = 26 2 hane =676 3 hane =17.576 4 hane =456.976 5 hane =11.881.376 6 hane =308.915.776 7 hane =8.031.810.176 8 hane =208.827.064.576 ( 208 milyar 827 milyon deneme yapılması gerektiriyormuş ) 9 hane =5.429.503.678.976 10 hane =141.167.095.653.376 11 hane =3.670.344.486.987.776 12 hane =95.428.956.661.682.176 13 hane =2,48115287320374E18 14 hane =6,45099747032972E19 15 hane =1,67725934228573E21 16 hane =4,36087428994289E22 17 hane =1,13382731538515E24 18 hane =2,94795102000139E25 bizden 8 haneli şifrelerden istenmiş. ve 123,456,780. sıradaki denenmesi gereken şifreyi sormuş vatandaş: = AAKKEEJS deneniyor olacakmış.... gerisini siz hesaplayın artık.. sonuçlar yukarda... ve key uzunluğu da 26! dikkatinizi çekerim küçük büyük harf ayrımı yapılmıyor... yapılsaydı key uzunluğu 92'ye kadar çıkardı.. rakamlar filan... eheh :) bekle dur... SORU 16: Bir program yazdınız, ve ini dosyalarını kullanıyorsunuz. Programınızın hangi işletim sisteminde çalışacağını bilmiyorsunuz. ( win9x de olabilir, w2k veya xp de olabilir.. ) aşağıdaki kodu YORUMLAYINIZ ? ( 250 puan ) (1770) procedure createini; var m,n:integer;ini:Tinifile; begin ini:=Tinifile.create('c:\deneme.ini'); try for m:=1 to 10000 do for n:=1 to 10 do begin ini.writestring('sinif'+inttostr(m),'deger'+inttostr(n),inttostr(n)); end; finally ini.free; end;//finally end; CEVAP: evet... mantıksal veya syntax hatası yok... yapılmak istenen olay "deneme.ini" dosyasına 10.000 adet sınıf (section) açtırmak ve her sınıfa 10 adet değer yazdırmak... Deneyimli bir programcı burada hemen şu soruyu sorar: 10x10.000 = 100.000 satır yapar! bu değirmenin suyunu işletim sistemi kaldırıyor mu peki?... açıklayayım: windows9x sistemlerde ini dosya kullanımı 64KB ile sınırlıdır... bu değeri aşmanız dahilinde sistem tarafından "insert line error!" hatası alırsınız ( satır yerleştirme hatası! ) windowsXP lerde ise böyle bir sorunu ortadan kaldırmışlar adamlar... bu yüzden xp 'yi inceledikçe adamlara "helal olsun, harbiden çekirdeği iyi tasarlamışlar" diyorum şimdi... xp sistemlerde 64KB diye bir sınır yok... açabildiğiniz kadar sınıf açabilirsiniz.. ve her türlü işlemi de üzerinde yapabilirsiniz... Bu olayı başıma gelen iyi bir tecrübeden sonra öğrendim... SORU 17: Ekran koruyucu şifresinin algoritmasını biliyorsunuz. Kodlanmış şekilde "37 38 44 45 34 36 32 44 35 37 35 39" verisini elde ettiğinizi varsayalım(registry kayıtlarından okutturdunuz), bunun karşılığı olan string veriyi elde edin ( ekran koruyucu şifresini elde etmiş olacaksınız ) ? ( 250 puan ) (2030) CEVAP: Ekran koruyucusunun şifresini kafaya takan programcılar bu şekilde stringlerle karşılaşmışlardır.. çünkü microsoft bunları kendi çapında kriptolamıştır... bu olayı ben 1999 yılında kafaya takmıştım ve sırf merakımdan dolayı bu kriptoyu çözmüştüm. HKEY_CURRENT_USER\control panel\desktop Bu anahtarda ekran koruyucu şifresi saklanmaktadır.. ve de-kriptosunu da aşağıya yayınlıyorum: 0= 37 38 44 45 34 36 32 44 35 37 35 39 39 31 32 42 1= 37 39 44 46 34 37 32 43 35 36 35 38 39 30 32 41 2= 37 41 44 43 34 34 32 46 35 35 35 42 39 33 32 39 3= 37 42 44 44 34 35 32 45 35 34 35 41 39 32 32 38 4= 37 43 44 41 34 32 32 39 35 33 35 44 39 35 32 46 5= 37 44 44 42 34 33 32 38 35 32 35 43 39 34 32 45 6= 37 45 44 38 34 30 32 42 35 31 35 46 39 37 32 44 7= 37 46 44 39 34 31 32 41 35 30 35 45 39 36 32 43 8= 37 30 44 36 34 45 32 35 35 46 35 31 39 39 32 33 9= 37 31 44 37 34 46 32 34 35 45 35 30 39 38 32 32 a= 30 39 41 46 33 37 35 43 32 36 32 38 45 30 35 41 b= 30 41 41 43 33 34 35 46 32 35 32 42 45 33 35 39 c= 30 42 41 44 33 35 35 45 32 34 32 41 45 32 35 38 ç= 38 46 32 39 42 31 44 41 41 30 41 45 36 36 44 43 d= 30 43 41 41 33 32 35 39 32 33 32 44 45 35 35 46 e= 30 44 41 42 33 33 35 38 32 32 32 43 45 34 35 45 f= 30 45 41 38 33 30 35 42 32 31 32 46 45 37 35 44 g= 30 46 41 39 33 31 35 41 32 30 32 45 45 36 35 43 h= 30 30 41 36 33 45 35 35 32 46 32 31 45 39 35 33 ı= 42 35 31 33 38 42 45 30 39 41 39 34 35 43 45 36 i= 30 31 41 37 33 46 35 34 32 45 32 30 45 38 35 32 j= 30 32 41 34 33 43 35 37 32 44 32 33 45 42 35 31 k= 30 33 41 35 33 44 35 36 32 43 32 32 45 41 35 30 l= 30 34 41 32 33 41 35 31 32 42 32 35 45 44 35 37 m= 30 35 41 33 33 42 35 30 32 41 32 34 45 43 35 36 n= 30 36 41 30 33 38 35 33 32 39 32 37 45 46 35 35 o= 30 37 41 31 33 39 35 32 32 38 32 36 45 45 35 34 ö= 39 45 33 38 41 30 43 42 42 31 42 46 37 37 43 44 p= 31 38 42 45 32 36 34 44 33 37 33 39 46 31 34 42 r= 31 41 42 43 32 34 34 46 33 35 33 42 46 33 34 39 s= 31 42 42 44 32 35 34 45 33 34 33 41 46 32 34 38 ş= 39 36 33 30 41 38 43 33 42 39 42 37 37 46 43 35 t= 31 43 42 41 32 32 34 39 33 33 33 44 46 35 34 46 u= 31 44 42 42 32 33 34 38 33 32 33 43 46 34 34 45 ü= 39 34 33 32 41 41 43 31 42 42 42 35 37 44 43 37 v= 31 45 42 38 32 30 34 42 33 31 33 46 46 37 34 44 y= 31 31 42 37 32 46 34 34 33 45 33 30 46 38 34 32 z= 31 32 42 34 32 43 34 37 33 44 33 33 46 42 34 31 q= 31 39 42 46 32 37 34 43 33 36 33 38 46 30 34 41 w= 31 46 42 39 32 31 34 41 33 30 33 45 46 36 34 43 x= 31 30 42 36 32 45 34 35 33 46 33 31 46 39 34 33 Her harfin bir karşılığı vardır. 2 sütundan oluşan... Bunu elle tek tek çıkarmıştım.. ve %100 olarak doğrulandığını defalarca kendime ispatladım. hem kendi pcimde hem de başka pclerde... kripto: "37 38 44 45 34 36 32 44 35 37 35 39" çözelim bakalım: Her iki rakamı sırayla "kolon"lardan bakıyoruz: 37 38 ="0" ( 1.kolon ) 44 45 = "0" ( 2.kolon ) 34 36 = "0" ( 3.kolon ) 32 44 = "0" ( 4.kolon ) 35 37 = "0" ( 5.kolon ) 35 39 = "0" (6. kolon ) ekran koruyucu şifremiz: "000000" miş.......... Bunu çözecek bir programı yazmaya hep üşenmişimdir..... SORU 18: Aşağıdaki kodu yorumlayınız ? ( 300 puan ) (2330) function tmy.hackx(sender:Tobject;h2:string):string; {h1:decode key} {h2:decode yapılacak password} var m,n:integer; h1,x,y,z:string; begin h1:=goldkey; for m:=1 to length(h2) do begin for n:=1 to length(h1) do begin x:=copy(h1,n,1); y:=copy(h2,m,1); if x=y then z:=z+chr(96+n); if y='b' then begin z:=z+'0';break;end; if y='c' then begin z:=z+'1';break;end; if y='d' then begin z:=z+'2';break;end; if y='e' then begin z:=z+'3';break;end; if y='f' then begin z:=z+'4';break;end; if y='g' then begin z:=z+'5';break;end; if y='h' then begin z:=z+'6';break;end; if y='i' then begin z:=z+'7';break;end; if y='j' then begin z:=z+'8';break;end; if y='k' then begin z:=z+'9';break;end; end; end; hackx:=z; end; {************** hack superonline 4.1*****************} procedure tmy.hackx2 (sender:Tobject;h2:string); {h2:decode yapılacak password-tam okunmuş hali} var m,n:integer; sonlandirici,x,z,crackx:string; ccrs:array[1..12] of byte; enkucuk:byte; begin {gerekli kısmı oku-şifre hane sayısı kadar oku, gerisini boşver} enkucuk:=99; for m:=1 to 12 do begin sonlandirici:=sol41key[m]; ccrs[m]:=1; if pos(sonlandirici,h2)>0 then begin ccrs[m]:=pos(sonlandirici,h2); //r1('m:'+inttostr(m)+'----pos:'+inttostr(ccrs[m])); if ccrs[m]<=enkucuk then enkucuk:=ccrs[m]-1; //break; end; end; //r1('şifre hane sayısı ----'+inttostr(enkucuk)); crackx:=copy(h2,1,enkucuk); //r1('default okunan şifre(registiry) :'+h2); //r1('son alınan h2 :'+crackx); //r1('sonlandırıcı string='+sol41key); {şimdi crackx stringini kır} x:=''; {şifre bu değişkene decode edilerek aktarılıyor} for m:=1 to enkucuk do for n:=1 to length(sol41keytr) do begin z:=sol41[n];{key şifre satırını al} if crackx[m]=z[m] then begin x:=x+sol41keytr[n]; //r1('m.şifre='+inttostr(m)+' n.satır='+inttostr(n)+' z(m)='+z[m]+' sonuç:'+sol41keytr[n]); break; end; end; sol41sifresi1:=x; {her türlü ihtimale karşı +5 ötelemeli okuma} enkucuk:=enkucuk+5; //r1('şifre hane sayısı ----'+inttostr(enkucuk)); crackx:=copy(h2,1,enkucuk); //r1('default okunan şifre(registiry) :'+h2); //r1('son alınan h2 :'+crackx); //r1('sonlandırıcı string='+sol41key); {şimdi crackx stringini kır} x:=''; {şifre bu değişkene decode edilerek aktarılıyor} for m:=1 to enkucuk do for n:=1 to length(sol41keytr) do begin z:=sol41[n];{key şifre satırını al} if crackx[m]=z[m] then begin x:=x+sol41keytr[n]; //r1('m.şifre='+inttostr(m)+' n.satır='+inttostr(n)+' z(m)='+z[m]+' sonuç:'+sol41keytr[n]); break; end; end; sol41sifresi2:=x; //r1('****** sonuç *****'); //r1('şifre ='+sol41sifresi1+sol41sifresi2); //form1.edit3.text:=crackx+'/'+x+'/'+inttostr(length(crackx)); end; CEVAP evet... 1999 yılında yazdığım tarihi kodlardan birisi... O zamanlar meşhur ve yaygın olarak kullanılan "superonline guide" internet bağlantı paketinin şifrelerini hiç bir program kıramıyordu.. çünkü "cached passwords" alanına kaydedilmiyordu.. böyle olunca da hiç bir trojan bu tip şifreleri söyleyemiyordu.. hikayesi uzun... welhasıl 6 saat uğraşıdan sonra sabaha karşı yukardaki kodları yazmıştım ( geliştirilmiş haliyle :] ) Ve öyle sanıyorum ki ilk çözen kişilerden birisiydim.... o zamanlar bunu kendimce bir .doc dosyasına yazmıştım, aynen aktarıyorum: " SUPERONLINE GUIDE 4.1 ,tqy'&-tul+x ixir 4.0.00 1-6-%$x)w)-*+#$%i{&xg-x*r}g+p-*)m. 1-7-%$x)w)|*+#$%i{&xg-x*r}g+p-*)m. 2-6-:;g6h6-*+#$%i{&xg-x*r}g+p-*)m. 2-7-:;g6h6c*+#$%i{&xg-x*r}g+p-*)m. 121212-?%;x6w6-*+#$%i{&xg-x*r}g+p-*)m. 1-$}% (vw|%$=z 2-;b:?7ihc:;"e 3-:c;>6hib;:#d 4-9`8=5kja89 g 5-8a9<4jk`98!f 6-?f>;3mlg>?&a 7->g?:2lmf?>'` 8-=d<91one<=$c 9-<e=80nod=<%b 0-%|$!)wv}$%<{ _-ODENH .-'~&#+ut&'>y q-ä½åà趷¼åäyº w-º§ÿúò¬­¦ÿºç e-è±éì亻°éèñ¶ r-û¢úÿ÷©¨£úû⥠t-ù øyõ«ª¡øùৠy-ü¥yø?®¯¤yüå¢ u-ø¡ùüôª« ùøᦠi-ìµíè྿´íìõ² o-æ¿çâê´µ¾çæÿ¸ p-å¼äáé·¶½äåü» a-MFGL<cr>? s-ú£ûºö¨©¢ûú㤠d-é°èí建±èé?· f-ï¶îëã½¼·îïö± g-î·ïêâ¼½¶ïî÷° h-í´ìé῾µìíô³ j-ãºâçï±°»âãú½ k-â»ãæî°±ºãâû¼ l-á¸àåí³²¹àáø¿ z-óªò÷ÿ¡ «òóê­ x-y¤üùñ¯®¥üyä£ c-ê³ëî渹²ëêó´ v-ÿ¦ºû󭬧ºÿæ¡ b-ë²êï繸³êëòµ n-ç¾æãëµ´¿æ纹 m-à¹áäì²³¸áàù¾ Sol 4.1 1-$}% (vw|%$=z 2-;b:?7ihc:;"e 3-:c;>6hib;:#d 4-9`8=5kja89 g 5-8a9<4jk`98!f 6-?f>;3mlg>?&a 7->g?:2lmf?>'` 8-=d<91one<=$c 9-<e=80nod=<%b 0-%|$!)wv}$%<{ _-ODENH .-'~&#+ut&'>y q-ä½åà趷¼åäyº w-º§ÿúò¬­¦ÿºç e-è±éì亻°éèñ¶ r-û¢úÿ÷©¨£úû⥠t-ù øyõ«ª¡øùৠy-ü¥yø?®¯¤yüå¢ u-ø¡ùüôª« ùøᦠi-ìµíè྿´íìõ² o-æ¿çâê´µ¾çæÿ¸ p-å¼äáé·¶½äåü» a-MFGL<cr>? s-ú£ûºö¨©¢ûú㤠d-é°èí建±èé?· f-ï¶îëã½¼·îïö± g-î·ïêâ¼½¶ïî÷° h-í´ìé῾µìíô³ j-ãºâçï±°»âãú½ k-â»ãæî°±ºãâû¼ l-á¸àåí³²¹àáø¿ z-óªò÷ÿ¡ «òóê­ x-y¤üùñ¯®¥üyä£ c-ê³ëî渹²ëêó´ v-ÿ¦ºû󭬧ºÿæ¡ b-ë²êï繸³êëòµ n-ç¾æãëµ´¿æ纹 m-à¹áäì²³¸áàù¾ J çöplük algoritması kullanmışlar.... sadece uğraştıracak.... sorun diil!! 38 x 12 = 456 işlem yapmam gerekiyor bir işlem 2 dk olsa, 2 x 456 = 912 dk = 15 saat sonra şifre kırılımı tamamdır J ehuhuheu.. ya işte 1 gün gitti buna da J ******* işte anahtar tablosu ******* JJJ 1 2 3 4 5 6 7 8 9 10 11 12 Ehu ehu , t q y ' & - t u l + x ”,tqy'&-tul+x” " Bu yöntemle birçok superonline guide şifresi ve mail şifresi elde etmiştim.. napyim coşmuştum :) daha sonra bunu admin@superonline.com adresine belirtsem de bir kaç mailleşmeden sonra kaile almadılar.. klasik zihniyet... bende 300e yakın bağlantı şifresi ve mail şifresini exelde hazırlayıp tekrar geri göndermiştim ve bunları kafamdan uydurmadığımı söylemiştim.. bana söyledikleri "CV nizi internet sayfamızda bulunan işbaşvuru formlarına belirtiniz. Gereken değerlendirme yapılacaktır".. yapmadım CV filan... öyle geçti zaman... Ama şayet işe girmiş olsaydım heralde döktürürdüm ve yeni "guide"lar yazardım !.. Daha sonra 2002 senesinde hackerpower.com adresinde coderlik yapan "phoex" arkadaşım da aynı kriptoyu elde etmiş ve bunu ufak bir programcıkla dile getirmişti... tabii ki tarih tekrardan ibarettir.. aynı tabloyu görünce phoex "shock" olmuştu haliyle :] Bu arada bu tip bağlantı şifrelerinin algoritmalarının young media tarafından yapıldığını belirtmek istiyorum.. superonline, guide, e-pack, kktc superonline, ixir paketlerinin tüm algoritmaları aynıydı... kendilerince cryptolamışlardı ama yetersizdi bence... İlk versiyonu olan 3.2 ve 4.0 sürümleri çok kolaydı.. daha sonra çıkan 4.1 ise yukarda bahsettiğim gibi daha karışıktı.. şimdi hangi versiyonu var bilmiyorum... tekrar mercek altına alacağım ama :] nostalji yaparım biraz... SORU 19: Aşağıdaki kodu YORUMLAYINIZ ? ( 300 puan ) (2630) deletefile('c:\windows\deneme\deneme.exe'); CEVAP: evet... Bu kod satırında ne var şimdi? diye sorabilirsiniz... mantık veya syntax hatası yok... ama oluşabilecek buglar dile getirilmeden yazılmış... Oluşabilecek buglar: 1. c:\windows\deneme\deneme.exe adlı dosya yerinde durmuyor olabilir.... böyle bir dosya yoktur belki?... 2. bu dosya o an için kullanılıyor olabilir.... 3. bu dosya o an için taşınıyor "move" olabilir... bu kodu bu şekilde direkt yazmaktan sa etkin bir function olarak tanımlanmalıydı bence.... function delfile(x:string):boolean; begin try if fileexists(x) then begin if notinuse(x) then //notinuse adlı başka bir function da yazıldığını varsayıyoum.. "=dosya kullanılmıyorsa" begin deletefile(x); result:=true; end else result:=false; end else result:=false; except result:=false; end; //final end; kullanımı da şu şekilde olacaktır: if delfile('c:\windows\deneme\deneme.exe') then showmessage('okey') else showmessage('silme işlemi başarısız'); finito....................... SORU 20: form üzerindeki herhangi bir memo nesnesi içerisine 1den 20.000e kadar olan sayıları yazdırınız. ( 390 puan ) (3000) CEVAP: evet... Bu soruda da ne var şimdi?... diye sorabilirsiniz... sazan bir coder hemen aşağıdaki kodu yazacaktır: ( eminim! çünkü hep gördüm... ) var m:integer; begin for m:=1 to 20000 do memo1.lines.add(inttostr(m)); end; finito mu ?..... hayır!... finito değil !... bu şekilde kod yazarsanız 2 saat beklersiniz.... sonra da apışıp kalırsınız niye tökezliyor program şimdi?.. diye... Ben şekilde yazmayı tercih ederdim: var tlist:Tstringlist;m:integer; begin tlist:=Tstringlist.create; for m:=1 to 20000 do begin tlist.add(inttostr(m)); tlist.savetofile('c:\memolist.txt'); memo1.lines.loadfromfile('C:\memolist.txt'); tlist.free; deletefile('C:\memolist.txt'); end; finito !!... temiz ve açık kod............ hafızada yapılan işlemlerle form üzerinde yapılan işlemler arasındaki farkları deneyimli bir coder her zaman için göz önünde bulundurur !.. yapılmak istenen işlem memo kutusuna 20.000 adet sayıyı yazdırmak, bunu illa memo üzerinde yapmanıza gerek var mı ?.... hayır gerek yok !.. hafızada yaptırıp sonra memo üzerine loadfromfile ile yükleme yaparsanız 2-3 sn kadar beklersiniz ve amacınıza ulaşırsınız.... GENEL: Evet arkadaşlar... Coderlik belki size sıkıcı geliyor olabilir.. ama şayet benim şahsi sitemi ziyaret ediyor iseniz bu konulara da meraklı olduğunuz yorumuna varırım doğal olarak.... ve ilginçtir hep genelde program kullanma taraftarıyız, ama oturup kendimiz yazmak istediğimizde de üfleyip püfleriz... ben her zaman şunu savunurum, kendin bir program istiyorsan otur kendin yaz !... yazamıyorsan öğren araştır tekrar gel yazmaya çalış!.. bu işi beceremiyorsan şayet bir daha bu tür işlere de bulaşma... ya salaksındır, ya da kafan biraz basıyodur... bunu söylerim hep kendime!... Tabii ki eski hızıma erişemiyorum artık... moruklaşıyoruz gün geçtikçe... bu da doğanın bir kanunu.. ve bu arada da son derece A-Sosyal olduğumu de anti-parantez belirtiyorum !. yaşasın kötülük ! :] Bu bir sevdadır bitmez Gönül bu ferman dinlemez... Coderlik bir hobidir bizde Nerden gelse bitmez... (amma salladım ha! :p ) kalın sağlıcakla... saygılarımla_ neoturk 02.03.2004