merhaba,
ferhat71 yazdı:arkadaşlar bu koddaki satırların ne anlama geldiğini açıklarsanız sevinirim.
bildiğim kadarıyla xor iki baytı karşılaştırıyor.orda "byte(S)" yazılacağına
"ord(S)" yazılsaydı olmazmıydı?
Stringler aslında bir char dizisi olarak bellekte tutulurlar.Ve bu dizinin ilk byte stringin uzunluğunu verir.bir örnek vermek gerekirse
gibi bir tanımlama yaptığımızda Str değişkenimiz için bellekte 11 byte yer ayrılır.Bunun ilk byte ı string değişkenimizin uzunluğu geri kalan 10 byte da değişkenimizin değerini içerecek.
bu atamada str için ayrılmış 11 byte uzunluğundaki belleğin içeriği şöyle olacak
s[0] = 10
s[1] = 'a'
s[2] = 'b'
s[3] = 'c'
s[4] = 'd'
s[5] = 'e'
s[6] = 'f'
s[7] = 'g'
s[8] = 'h'
s[9] = 'i'
s[10] = 'z'
o halde "Result[0] := S[0]" satırı fonksyondan (Result) dönecek değerin uzunluğu ile parametre olarak aldığımız "s" değerinin uzunluğunu birbirine eşitler.Böyle bir eşitleme yapmamızın sebebi ise daha sonra result'un her byte na tek tek atama yapmamız gerektiği içindir. burada "Result := S" yapmamızda aslında bize aynı sonucu verecektir.(Tam olarak olmasada!)
Şimdi Decrypt fonksiyonuunda kullanılan diğer fonksiyonları incelemeden bir süreliğine bitlere kadar inip bellekte asıl olarak neler yapıldığına daha yakından bakalım.
bellekte (bilgisayarda) herşey bir dizi "1" ve "0" dan oluşur.Burada "0" ve "1" değerini alan bu anahtarlara bit diyoruz. Anlamlı olabilecek en küçük değeri ancak 8 bit ile ifade edebiliyoruz ki bu 8 bite de byte denir.Örnek olarak "A" harfinin bellekteki görünüşü şöyledir.
"A" ascii tablosunda 65 ile ifade edilir 65 in ise ikilik koddaki gösterimi budur.
Bir bitle sadece iki değeri ifade edbiliriz."0" ve "1". iki bitle ise "00", "01", "10","11'. toplam 2^2 = 4.
bu formülden 8 bitle 2^8 = 256 farklı değeri ifade edebiliriz.
gibi bir tanımlamayla bellekte pozitif bir sayı tutmak için bir byte'lık bir yer ayırmış oluruz.Bir byte ile ifade edebileceğimiz en küçük ve en büyük sayılar
Kod: Tümünü seç
0 0 0 0 0 0 0 0 = 0
1 1 1 1 1 1 1 1 = 255
en küçüğü 0 ve en büyüğü 255 olmak üzere toplam 256 adet farklı değer.
gibi bir tanımlamayla a değişkeni için bellekte iki byte yer ayırmış oluruz ki buradada ifade edebileceğimiz
2^16 = 65536 farklı değer olur.en büyüğü 65535.
peki ya negatif sayılar.
negatif sayıları ifade etmek için en yüksek anlamlı bit (en soldaki bit) işaret biti olarak kabul edilir.Pozitif sayılar için "0" negatif sayılar için "1" ile ifade edilir.
tanımlamasıyla bellekte bir sayı tutmak için (negatif yada pozitif) bir byte lık yer ayrılır.
Kod: Tümünü seç
Değer bellek
------------ ---------------
A := 1; 0 0 0 0 0 0 0 1
A := 2; 0 0 0 0 0 0 1 0
A := -1; 1 0 0 0 0 0 0 1 (?????)
Pozitif sayıları ifade etmek için ilk biti işaret biti olarak kullandığımızda geriye elimizde 7 bit kalır ki bununlada ifade edebileceğimiz en büyük sayı
Kod: Tümünü seç
0 1 1 1 1 1 1 1 = 127 olur.
- - - - - - - -
i.b
-1 i ifade etmek için ilk akla gelen
Kod: Tümünü seç
1 0 0 0 0 0 0 1
- - - - - - - -
İ.B (İ.B: İşaret biti)
şeklinde olmaz.Aslında negatif sayılar ilk biti işaret biti olmak üzere geri kalan bitlerin 2 ye tümleyeni şekline gösterilir.2 ye tümleyen ise 1 e tümleyenin (yani "0" ise "1", "1" ise "0") 1 fazlası alınarak elde edilir.örnek olarak "-1" i iafade etmek için "1", 2 ye tümleyerek gösterelim.
Kod: Tümünü seç
0 0 0 0 0 0 0 1 = 1
1 1 1 1 1 1 1 0 ---> 1 e tümleyeni
+ 1
1 1 1 1 1 1 1 1 ---> (2 ye tümleyen yani "-1" bellekteki görüntüsü)
2 ye tümleyeni bulmanın kısa yolu : ikiye tümleyeni kısa yoldan yapmak için en sağdaki bitten başlayarak sola doğru ilk "1" e kadara olan bitleri değiştirmeden bırakıp sonraki bitleri 1 e tümlemeyerek sonuca ulaşabiliriz.
"-1" in "1 1 1 1 1 1 1 1" şekilinde gösterildiğini gözlerinizle görmek için formun üzerine bir buton ve bir edit koyarak button1.onclik olayna şu kodu yazın.
Kod: Tümünü seç
var
a: Shortint;
sayac: Integer;
begin
Edit1.Clear;
a := -1;
for sayac := 0 to 7 do
Edit1.Text := InttoStr((a shr sayac) And 1) + Edit1.Text;
end;
Decrypt fonksiyonunu incelemeye devam edelim.
ord / byte : karakterin ascii kodunu verir. Ord('A') = 65 Ord('B') = 66... gibi.
Chr : Ord fonksiyonunun tersini yapar. Chr(65) = 'A' gibi.
shr, shl : bit düzeyinde işlem yapar. örnek olarak
65 syısının ("A" karakteri) bellekte nasıl tutulduğuna bakalım.
Kod: Tümünü seç
0 1 0 0 0 0 0 1 ("A" karakteri bellekte bu şekilde tutuluyor.)
- - - - - - - -
Shr bu yapıyı (bitleri) bir derece sağa öteler SHR(ight)
Shl bu yapıyı bir derece sola öteler SHL(eft)
buradan yola çıkarsak
(65 shr 1) = (01000001 shr 1) = (00100000) = 32 olur. Yani bir derece sağa kaydırınca yarısını almış oluyoruz(daha doğrusu div 2).Bir de tersini yapalım
(32 shl 1) = (00100000 shl 1) = (0100000000) = 64 oldu.
özetlemek gerekirse
A * 2 = (A shl 1)
A div 2 = (A Shr 1) oldu.
lojik kapılar(And, Or, Xor, Not):
Kod: Tümünü seç
And | 1 0 Or | 1 0 Xor | 1 0
------------ ------------ ------------
1 | 1 0 1 | 1 1 1 | 0 1
------------ ------------ ------------
0 | 0 0 0 | 1 0 0 | 1 0
------------ ------------ ------------
And, Or ve Xor işlenecek iki değeri alarak sonuç üretir."Not" operatörü ise adı üstünde tersini alır.Yani
Not(1) = 0 ve Not(0) = 1, Not (1 and 0) = 1 gibi.
yukarıdaki örnekten yola çıkarsak iki byte xor kapısından şöyle alabiliriz.
(00100101 xor 11101001) = (11001100) olur.işlemi daha iyi görmek için alt altta yazıyorum.
Kod: Tümünü seç
00100101
11101001 XOR
-------------------
11001100
bir değeri iki defa aynı değerle xor kapısından geçirirsek yine ilk değeri elde ederiz.Örnek
1 Xor 1 Xor 1 = 1
1 Xor 0 xor 0 = 1
0 xor 1 xor 1 = 0
0 xor 0 xor 0 = 0
o halde Decrypt fonksiyonundaki
Kod: Tümünü seç
Key := (byte(S[I]) + Key) * C1 + C2;
satırını aradan çıkarırsak
Kod: Tümünü seç
function DecryptAndEncrypt(const S: String; Key: Word): String;
var
I: byte;
begin
Result[0] := S[0];
for I := 1 to Length(S) do
Result[I] := char(byte(S[I]) xor (Key shr 8));
end;
elde edeceğimiz bu DecryptAndEncrypt fonksiyonu hem şifreleme yapar hemde bu şifreyi çözer.DecryptAndEncrypt fonksiyonunun Decrypt fonksiyonuna göre çözülmesi daha kolay bir şifreleme yapacağı açıktır.Ayrıca bu fonksiyonun şifreleme yapabilmesi için "key" parametresinin değeri en az 256 olmalıdır.Çünkü 256 dan daha küçük değerler ancak en sağdaki 8 biti değiştireceğinden ve biz (Key shr

yani bu sayıyı bit düzeyinde 8 defa sağa öteleyeceğimizden her zaman "0" ile xor kapısını girecektir ki dolayısıyla gönderdiğimiz stringi olduğu gibi geri almış oluruz.Demekki Decrypt fonksiyonun anahtarı
Kod: Tümünü seç
Key := (byte(S[I]) + Key) * C1 + C2;
satırıdır.Eğer ben bu satırdaki işlemlerin tersini yapan bir kod yazarsam encrypt fonksiyonunu bulmuş olurum.Örnek olarak encrypt fonksiyonuna bir alternatif yazmaya çalışalım.
Kod: Tümünü seç
01 function Decrypt(const S: String; Key: Word): String;
02 var
03 I: byte;
04 begin
05 Result[0] := S[0];
06 for I := 1 to Length(S) do begin
07 Result[I] := char(byte(S[I]) xor (Key shr 8));
08 Key := (byte(S[I]) + Key) * C1 + C2;
09 end;
10 end;
burada
Kod: Tümünü seç
Result[I] := char(byte(S[I]) xor (Key shr 8));
her seferinde
Kod: Tümünü seç
Key := (byte(S[I]) + Key) * C1 + C2;
satırında belirlenen "key" e göre bir karakteri şifreler.Bunun tersini yapmam için Encrypt fonksiyonunda bana gelen S
zaten şifrelenmiş olduğundan ilk önce bu şifreyi çözerek
Kod: Tümünü seç
Key := (byte(S[I]) + Key) * C1 + C2;
satırına girmesini sağlarımki o da şu şekilde olur.
şimdi bunu gerekli yere yazarsam
Kod: Tümünü seç
Key := (byte(S[I]) + Key) * C1 + C2;
satırının tersi
Kod: Tümünü seç
Key := ((Ord(S[I]) xor (Key shr 8)) + Key) * C1 + C2;
olur.
şimdi Encrypt fonksiyonunun tamamı şu şekilde olur.
Kod: Tümünü seç
function TForm1.Encrypt(const S: String; Key: Word): String;
var
I: byte;
begin
Result := S;
for I := 1 to Length(S) do begin
Result[I] := Char(Ord(S[I]) xor (Key shr 8));
Key := ((Byte(S[I]) xor (Key shr 8)) + Key) * C1 + C2;
end;
end;
son olarak C1 ve C2 sabitlerine bakalım.
olarak tanımlanmışlarıdır.Oysa bizim fonksiyonlarımızdaki "Key" parametresi word olarak tanımlanmıştır ve word olarak tanımlanmış bir değişkenin alabileceği max değer
Kod: Tümünü seç
word := 0..65535 dir.
Key := (byte(S[I]) + Key) * C1 + C2; stırında
------------------
x
x'in alabileceği en küçük değerde bile ( 1 * 52845 + 22719) "Key" değişkenimiz sınırlarını aşacaktır.
iyi çalışmalar.