Kodun Kısa Açıklaması:
Kullanıcıdan anahtar metnini istiyoruz ve metnin uzunluğunu hesaplıyoruz.
Bu programda öteleme işlemlerini kullanacağımız için her dizinin bitiş indisini
tutuyoruz. Anahtarı aldıktan sonra içinde tekrar eden harfleri siliyoruz. Bu
silme işlemini de bahsettiğimiz gibi sola bir kere öteleme yaparak
hallediyoruz. Tekrarları sildikten sonra bu dizinin harflerini başta
tanımladığımız alfabe dizisinden çıkartıyoruz. Tekrarları sildiğimiz dizinin
elemanlarını alfabe dizisinin başına kopyalamamız gerekiyor. Bunun için de
alfabe dizisini sağa doğru ötelememiz gerekiyor(tekrarsız kalan harf sayısı
kadar). Alfabe dizisinin başına gerekli kopyalamaları yaptıktan sonra bu diziyi
tabloya atıyoruz.
Kullanıcıdan şifrelenecek metni girmesini istiyoruz ve ikili olarak
kontrole başlıyoruz. İkililerden aynı karakter olan varsa arasına yine öteleme
işlemi yaparak ‘X’ karakterini yerleştiriyoruz. Tüm diziye bunu uyguladıktan
sonra eğer en son eleman tek kalmışsa dizi sonuna da ‘Z’ karakterini ekliyoruz.
Fakat bu son eleman da ‘Z’ ise programımızın sonsuz döngüye girmesini
engellemek için ‘X’ karakterini ekliyoruz. Şifreleme işlemine geldiğinde ise
her ikili karakterleri bir anda tabloda arıyoruz. Bulduğumuz karakterlerin adreslerini
tablo adlı 2x2 lik matriste tutuyoruz. Örneğin HC ikilisini arıyoruz ve
bulduğumuzda H karakterinin satır numarasını tutac[0][0] ’a H karakterinin
sutun numarasını tutac[0][1] ‘e ; C karakterinin satır numarasını tutac[1][0]
’a C karakterinin sutun numarasını
tutac[1][1] ‘e kaydediyoruz. Daha
sonra bunların aynı satırda-sütunda olup olmadığına bu tutaç matrisini
kullanarak bakıyoruz ve hemen şifrelenmiş şeklini şifrelenmiş string’i tutacak
diziye atıyoruz. Bu işlemleri şifrelenecek string’in sonuna kadar yapıyoruz ve
şifreyi ekrana yazdırıyoruz.
Kodun Ayrıntılı Açıklaması:
Problemin çözüm kısmında
öncelikle kullanıcıdan anahtar olacak metni büyük harflerle girmesini istiyoruz
ve strlen fonksiyonunu kullanarak girilen dizinin son karakterinin indisini
buluyoruz. Daha sonra ilk işimiz girilen bu anahtardaki tekrar eden harfleri
çıkartmaktır. Bunu da bir while döngüsü kullanarak yapıyoruz. While döngüsünde
aynı harflerin olup olmadığına bakıyoruz. Eğer aynı harfler varsa ikinci olarak
bulunan harfi silmemiz gerekiyor. Bu işlemi de o harfin olduğu yere bir kere
öteleyerek yapıyoruz. Burada ötelemeden sonra i değişkenini bir azaltmamızın
sebebi sildiğimiz harfin üstüne aynı harf geldiği zaman tekrar silmesi
gerektiğidir.
Bahsettiğim başa dönme
olayından dolayı bu işlemleri en başta for ile değil de while ile yaptık çünkü
for döngüsündeki i değişkenine müdahale etmemiz gerekecekti ve for döngüsünde
bu azaltma işlemini yapmak hiç sağlıklı değildir.
Anahtar dizimizdeki
tekrarlı harfleri çıkarttıktan sonra geriye kalan harfleri alfabe dizisinden
çıkartmamız gerekiyor çünkü tablomuza alfabede kalan harfleri sırayla
ekleyeceğiz.
Tabloya ekleyeceğimiz
harfleri alfabe dizisinden alacağız. Bu yüzden sırayla, önce tekrar eden
harfleri çıkarttığımız dizideki harfleri alfabe dizisine almalıyız. Bunu da
yapmak için öncelikle alfabeden sildiğimiz harf kadar sağa öteleme yapmalıyız
ki alfabe dizisinin başına tekrarsız harfleri ekleyebilelim.
Öteleme işlemini
yaptıktan sonra anahtar dizisinde kalan harfleri sırayla alfabe dizisine
atıyoruz. Artık alfabe dizisini tabloya atarak şifre metinini kullanıcıdan
istiyoruz.
Bu bölümde öncelikle
girilen string’i ikili parçalara ayırıp aynı harf ikililerinin olup olmadığına
bakıyoruz. Eğer böyle ikililer varsa o ikililerin arasına ‘X’ karakterini
yerleştiriyoruz. Bu işlemi dizinin
sonuna kadar yapıyoruz. Bu işlemleri tamamladıktan sonra eğer en sonda tek
karakter kaldıysa onu ikili yapmak için
string’in sonuna ‘Z’ ekliyoruz ve dizinin uzunluğunu bir arttırıyoruz. Eğer son
eleman da ‘Z’ ise dizinin sonuna sonsuz döngüyü engellemek için ‘X’ karakterini
ekleriz. Dizilerde son elemanı
tutmaktaki amaç öteleme yaptığımız zaman kalan elemanların da diziye dâhil
olduğu fakat kullanılmadığından dolayı dizinin asıl son elemanını bulabilmemiz.
Görsel amaçlı olarak kullanıcıya burada bir de şifrelenecek string’in son
halini gösteriyoruz.
En son olarak geriye
string’i şifrelemek kalıyor. İ değişkenini 0’dan dizi uzunluğuna kadar ikişer
olarak arttırıyoruz. Bunu yapmamızdaki amaç her ikilileri bir adımda
bulacağımız için teker teker gitmeye gerek kalmamasıdır. Tutaç adlı 2x2 lik matrisimiz
bize bulunan harflerin tablodaki indislerini gösterecektir.
Örneğin:
2
|
4
|
1
|
3
|
Yukarıdaki tablo bulunan birinci harfin satır sayısının 2 Sütun sayısının 4 olduğunu, ikinci harfin de satır sayısının 1 sütun sayısının 3 olduğunu gösteriyor.
Programın devamında24’e kadar giden
bir t değişkeni tanımladık. Bu bize bulunduğumuz satır ve sütunu verecek. Eğer
burada for döngüsü kullansaydık her eleman için 25 elemanı da kontrol etmek
zorunda kalacaktık. Örneğin t=13 durumunda satır sayısını 13/5 den 2, sütun
sayısını da 13 (mod5 )‘ten 3 olarak bulacağız. Şifrelenecek iki harfin de Satır
ve sütun numaralarını bulduktan sonra aynı satır-sütunda olduğuna ya da
olmadığına bakıyoruz. Eğer aynı satırdalarsa yanlarındaki, aynı sütundalarsa
altlarındaki, ikisi de değilse köşelerindeki elemanları alıyoruz. Bunu tüm
stringi dolaşarak yapıyoruz ve bulduğumuz her şifreli harfleri şifre için
tanımladığımız diziye atıyoruz. En son da şifrelenmiş string’i ekrana
yazdırıyoruz ve programımızı bitiriyoruz.
Programın Kaynak Kodu:
#include <stdio.h>
#include <stdlib.h>
int main() {
char tablo[5][5];
char anahtar[25];//GİRİLECEK ANAHTAR İÇİN KULLANILACAK DİZİ
char sifrelenmis_dizi[25];//ŞİFRELENEN HARFLERİN YAZILACAĞI DİZİ
int tutac[2][2];//TABLODA ARANIP-BULUNAN 2 HARFİN ADRESLERİNİN TUTULACAĞI DİZİ
char alfabe[25]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','R','S','T','U','X','V','W','Y','Z'};
char sifrelenecek_dizi[30];//ŞİFRELENMEK İÇİN GİRİLEN DİZİ
int i,j,k,t,indis;
int anahtar_dizi_sonu;//ANAHTAR DİZİSİNİN SON İNDİSİNİ TUTAN DEĞİŞKEN
int alfabe_sonu=24;
int sifrelenecek_dizi_uzunlugu;
int sifre_onay=0;
printf("Lutfen anahtar metnini buyuk harflerle giriniz !!\n");
scanf("%s",&anahtar);
anahtar_dizi_sonu=strlen(anahtar)-1;
i=1;
while(i<=anahtar_dizi_sonu){
j=0;
while(anahtar[j]!=anahtar[i] && j<i){
j++;
}
if(j!=i){
for(k=i;k<anahtar_dizi_sonu;k++){
anahtar[k]=anahtar[k+1];
}
anahtar_dizi_sonu--;
i--;
}
i++;
}//AYNI HARFLER BULUNUP DİZİDEN ÇIKARTILIYOR
for(i=0;i<=anahtar_dizi_sonu;i++){
j=0;
while(anahtar[i]!=alfabe[j] ){
j++;
}
for(k=j;k<alfabe_sonu;k++){
alfabe[k]=alfabe[k+1];
}
alfabe_sonu--;
}//GİRDİĞİMİZ ANAHTARDAKİ HARFLER ALFABEDEN ÇIKARTILIYOR
for(i=alfabe_sonu;i>=0;i--)
{
alfabe[i+anahtar_dizi_sonu+1]=alfabe[i];
}//SİLİNEN HARFLER KADAR ALFABE DİZİSİNİ SAĞA ÖTELİYORUZ VE ANAHTARDAKİ HARFLERE YER AÇIYORUZ
for(i=0;i<=anahtar_dizi_sonu;i++){
alfabe[i]=anahtar[i];
}//ALFABE DİZİSİNDE AÇTIGIMIZ YERLERE TEKRARSIZ ANAHTAR HARFLERİMİZİ YERLEŞTİRİYORUZ
printf("\nGirdiginiz anahtarin tekrarsiz harfli formati asagidaki gibidir:\n\n");
for(i=0;i<=anahtar_dizi_sonu;i++){
printf("%c",anahtar[i]);
}
strcpy(tablo,alfabe);//ALFABE DİZİMİZİ TABLOYA YERLEŞTİRİYORUZ
printf("\n\nAnahtar yerlestirilmis tablo asagidaki gibidir!!\n\n");
for(i=0;i<5;i++)
{
for(j=0;j<5;j++){
printf("%c ",tablo[i][j]);
}
printf("\n");
}
printf("\nLutfen sifrelenecek metni giriniz!!\n");
scanf("%s",&sifrelenecek_dizi);
sifrelenecek_dizi_uzunlugu=strlen(sifrelenecek_dizi);
indis=0;
while(indis<sifrelenecek_dizi_uzunlugu){
if(sifrelenecek_dizi[indis]==sifrelenecek_dizi[indis+1]){
for(j=strlen(sifrelenecek_dizi)-1;j>indis;j--){
sifrelenecek_dizi[j+1]=sifrelenecek_dizi[j];
}
sifrelenecek_dizi_uzunlugu++;
sifrelenecek_dizi[indis+1]='X';
}
else{
indis=indis+2;
}
}//AYNI HARF OLAN İKİLİLER VARSA ARAYA 'X' YERLEŞTİRİYORUZ
if(sifrelenecek_dizi_uzunlugu%2==1){
if(sifrelenecek_dizi[sifrelenecek_dizi_uzunlugu-1]=='Z'){
sifrelenecek_dizi[sifrelenecek_dizi_uzunlugu]='X';
sifrelenecek_dizi_uzunlugu++;
}//EN SON HARF 'Z' İSE SONUNA 'X' EKLİYORUZ
else{
sifrelenecek_dizi[sifrelenecek_dizi_uzunlugu]='Z';
sifrelenecek_dizi_uzunlugu++;
}//EN SON HARF TEK KALMIŞSA SONUNA 'Z' EKLİYORUZ
}
printf("\nGirdiginiz metnin sifrelenmeye uygun son hali :\n\n");
for(i=0;i<sifrelenecek_dizi_uzunlugu;i++){
if(i%2==0&&i!=0){
printf("-");
}
printf("%c",sifrelenecek_dizi[i]);
}
printf("\n\n ***ACIKLAMALAR***\n");
for(i=0;i<sifrelenecek_dizi_uzunlugu;i=i+2){
for(k=i;k<i+2;k++){
t=0;
while(sifrelenecek_dizi[k]!=tablo[t/5][t%5]){
t++;
}
tutac[k%2][0]=t/5;
tutac[k%2][1]=t%5;
}
if(tutac[0][0]==tutac[1][0]){
sifrelenmis_dizi[i]=tablo[tutac[0][0]][(tutac[0][1]+1)%5];
sifrelenmis_dizi[i+1]=tablo[tutac[1][0]][(tutac[1][1]+1)%5];
printf("\n%c ve %c ayni satirdadirlar!!\n",tablo[tutac[0][0]][tutac[0][1]],tablo[tutac[1][0]][tutac[1][1]]);
}//AYNI SATIRDALARSA
else{
if(tutac[0][1]==tutac[1][1]){
sifrelenmis_dizi[i]=tablo[(tutac[0][0]+1)%5][tutac[0][1]];
sifrelenmis_dizi[i+1]=tablo[(tutac[1][0]+1)%5][tutac[1][1]];
printf("\n%c ve %c ayni sutundadirlar!!\n",tablo[tutac[0][0]][tutac[0][1]],tablo[tutac[1][0]][tutac[1][1]]);
}//AYNI SUTUNDALARSA
else{
sifrelenmis_dizi[i]=tablo[tutac[0][0]][tutac[1][1]];
sifrelenmis_dizi[i+1]=tablo[tutac[1][0]][tutac[0][1]];
printf("\n%c ve %c ayni satir-sutunda degildirler!!\n",tablo[tutac[0][0]][tutac[0][1]],tablo[tutac[1][0]][tutac[1][1]]);
}//AYNI SATIR VEYA SUTUNDA DEĞİLLERSE
}
}
printf("\n\nMetnin sifrelenmis hali asagidaki gibidir:\n");
for(i=0;i<strlen(sifrelenmis_dizi);i++){
if(i%2==0&&i!=0){
printf("-");
}
printf("%c",sifrelenmis_dizi[i]);
}
return 0;
}
Hiç yorum yok:
Yorum Gönder