Vigenere Şifreleme Programı C#

Vigenere Şifreleme Programı (C#)

Blaise de Vigenère

Blaise de Vigenère, 1523-1596 yılları arasında yaşamış Fransız bir diplomattır. Roma’da görev yaptığı esnada kriptografi ile ilgilenmeye başlamış. O dönemde İtalya, Avrupa şifrebiliminin merkeziymiş. Vigenere emekliliği sırasında çeşitli konular üzerine kitaplar yazmış. Bunlardan birisi Traictè des Chiffres ou Secrètes Manières d’Escrire (1586) idi. Kitapta Giovan Battista Bellaso’nun Tabula Recta (Kademeli Sezar şifreleme sistemi) şiflemesi dahil, çeşitli kod ve şifreleri incelemiş. Tabula Recta 19. yüzyılda yanlışlıkla de Vigenere‘e atfedilmiş. Vigenere, Bellaso’nun şifreleme yöntemini daha da geliştirerek kendi Vigenere şifreleme yöntemini oluşturmuş. Bu yöntemde tabloyu 26×26’ya genişletmiş ve şifreleme için otomatik anahtar sistemini ortaya atmış.

Sistem, şifrebilim tarihinde bir dönüm noktası olmuş ve gizli mesaj gönderiminde, özellikle de savaş dönemlerinde çok güvenli bir yol sağlamış. 19. yüzyıl sonuna dek kullanılan bu sistem öyle güvenli görülüyormuş ki kırılmaz şifre diye anılıyormuş.

Blaise de Vigenere (Vigenere Şifreleme)
Blaise de Vigenère (1523 – 1596)

Vigenere Şifreleme Algoritması

Başlamadan önce programın nasıl çalıştığını gösterdiğim YouTube videosunu izleyebilirsiniz:

Vigenere şifreleme algoritması, Sezar şifreleme algoritmasının geliştirilmiş bir versiyonudur. Eğer sezar şifreleme yöntemini bilmiyorsanız, öncelikle onu öğrenmenizi tavsiye ediyorum. Bir önceki yazımda Sezar şifreleme yöntemini anlattım.

Not: Vigenere Şifreleme programında, Sezar şifreleme programındaki gibi ASCII  tablosunu kullanıyorum. Bu yüzden Türkçe karakterler işlemiyor.

Sezar şifreleme yönteminde, anahtar sayı kullanarak alfabeyi ne kadar kaydıracağımızı belirliyorduk. Vigenere şifreleme yönteminde de alfabeyi kaydırıyoruz. Fakat, Sezar şifreleme yönteminden farklı olarak “anahtar sayı” yerine, “anahtar kelime” veya “anahtar metin” kullanıyoruz.

Buradaki yöntem, anahtar kelimedeki harfin alfabede kaçıncı sırada olduğuna bakmak üzerine kurulu. Anahtar kelimedeki harf alfabede kaçıncı sıradaysa, alfabeyi o kadar ileri kaydırıyoruz. Örneğin şifrelenecek harf olarak, J harfini kullanalım. Anahtar kelimemizdeki harf ise E harfi olsun. E harfi alfabede 4. sırada bulunuyor (A‘nın alfabedeki sırasını 0 olarak varsayıyorum ve türkçe karakterleri hesaba katmıyorum). Bu durumda J harfinden 4 sonraki N harfi, şifrelenmiş harfimiz oluyor (JKLMN)

Vigenere şifreleme örneği

Vigenere şifrelemede anahtar kelime, şifrelenecek yazı bitene kadar kendini tekrar ediyor. Örneğin “HELLO” kelimesini “ABC” anahtar kelimesiyle şifreleyelim. A harfinin alfabedeki sırası 0, B’nin 1, C’nin 2.

Örnek tablo (“HELLO” kelimesinin “ABC” anahtar kelimesiyle şifrelenmesi)

Düz Metin H E L L O
+ Anahtar A B C A B
0 1 2 0 1
Şifreli Metin H F N L P

Aşağıdaki tablo üzerinden bütün harfleri kontrol edebilirsiniz.

Vigenere şifreleme tablosu
Vigenere şifreleme tablosu

Şifrelenen Harfin Alfabedeki Sıra Numarasını Öğrenmek

Şifrelenen harfin alfabedeki sırası = (Şifrelenecek harfin alfabedeki sırası + Anahtar kelimedeki harfin alfabedeki sırası) mod 26

Sezar şifreleme formülünden tek farkı, anahtar sayı yerine anahtar kelimedeki harfin alfabedeki sıra numarasını koymak.

Vigenere Şifreleme Programının Kodları

Programı Visual Studio ortamında Windows Forms Uygulaması olarak yazdım. Dil olarak C# kullandım. Bir görsel arayüz hazırladım. Bu görsel arayüzle hem bir metni şifreleyebiliyor hem de deşifre edebiliyorsunuz.

Vigenere Şifreleme Programı Arayüzü
Uygulamanın arayüz ekranı

Vigenere Şifreleme ve Deşifre Etme Sınıfının Kodları

Yazdığım sınıfın kodlarını Github’da incelemek için tıklayın.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VigenereCipher
{
    class VigenereCipher
    {
        // Kullanıcının yazdığı anahtar kelime
        private string anahtar_kelime;
        // Kullanıcının yazdığı anahtar kelimenin karakter sayısı
        private int anahtar_kelime_length;
        // Kullanıcının yazdığı anahtar kelime için sayaç
        private int anahtar_kelime_sayac;
        // Kullanıcının yazdığı yazı
        private string kullanici_yazi;
        // Şifrelenen ya da deşifre edilen yazı
        private string sifre_yazi;

        // Kurucu metod yazdım. Sınıfın nesnesini oluştururken kullanıcıdan anahtar kelime ve şifre-deşifre edilecek yazıyı alıyorum 
        public VigenereCipher(string anahtar_kelime, string sifre_yazi)
        {
            this.anahtar_kelime = anahtar_kelime;
            this.kullanici_yazi = sifre_yazi;
            this.anahtar_kelime_length = anahtar_kelime.Length;
        }

        // ASCII tablosu kullanarak şifreleme yaptığım için, Türkçe karakterleri kontrol etmek adına bool fonksiyon yazıyorum
        private bool TurkceMi(char karakter)
        {
            if (karakter == 'ç' || karakter == 'Ç' || karakter == 'ğ' || karakter == 'Ğ' || karakter == 'ı' || karakter == 'İ' || karakter == 'ö' || karakter == 'Ö' || karakter == 'ş' || karakter == 'Ş' || karakter == 'ü' || karakter == 'Ü')
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // Anahtar kelimenin İngilizce karakterler dışında karakter içerip içermediğini kontrol eden fonksiyon
        public bool AnahtarKelimeAlfabetikMi()
        {
            bool sonuc = true;

            for (int i = 0, s = anahtar_kelime_length; i < s; i++)
            {
                if (char.IsLetter(anahtar_kelime[i]) && !TurkceMi(anahtar_kelime[i]))
                {
                    continue;
                }
                else
                {
                    sonuc = false;
                    break;
                }
            }

            return sonuc;
        }

        // "Sifrele" metodunu kullanarak yazının şifrelenmiş halini gönderiyorum
        public string Sifrele()
        {
            // Metod her çalıştırıldığında sifre_yazi değişkenini boş hale getiriyorum
            sifre_yazi = "";
            anahtar_kelime_sayac = 0;

            for (int i = 0, s = kullanici_yazi.Length; i < s; i++)
            {
                // Eğer karakterler harf ise ve Türkçe karakter değilse Vigenere şifreleme formülü uygulanıyor
                if (char.IsLetter(kullanici_yazi[i]) && !TurkceMi(kullanici_yazi[i]))
                {
                    // Vigenere formülü için integer değişken oluşturuyorum
                    int formul;

                    // Karakter büyük harfse formül bu şekilde oluyor
                    if (char.IsUpper(kullanici_yazi[i]))
                    {
                        formul = ((kullanici_yazi[i] - 65) + (char.ToUpper(anahtar_kelime[anahtar_kelime_sayac % anahtar_kelime_length]) - 65)) % 26;
                        sifre_yazi += (char)(formul + 65);
                        anahtar_kelime_sayac++;
                    }
                    // Karakter küçük harfse formül bu şekilde oluyor
                    else
                    {
                        formul = ((kullanici_yazi[i] - 97) + (char.ToLower(anahtar_kelime[anahtar_kelime_sayac % anahtar_kelime_length]) - 97)) % 26;
                        sifre_yazi += (char)(formul + 97);
                        anahtar_kelime_sayac++;
                    }
                }
                // Eğer karakterler harf değilse ve Türkçe ise, olduğu gibi sifre_yazi değişkenine aktarılıyor
                else
                {
                    sifre_yazi += kullanici_yazi[i];
                }
            }

            // Şifrelenmiş yazıyı gönderiyorum
            return sifre_yazi;
        }

        // "DesifreEt" metodu kullanarak yazının deşifre edilmiş halini gönderiyorum
        public string DesifreEt()
        {
            // Metod her çalıştırıldığında sifre_yazi değişkenini boş hale getiriyorum
            sifre_yazi = "";
            anahtar_kelime_sayac = 0;

            for (int i = 0, s = kullanici_yazi.Length; i < s; i++)
            {
                // Eğer karakterler harf ise ve Türkçe karakter değilse Vigenere şifreleme formülü uygulanıyor
                if (char.IsLetter(kullanici_yazi[i]) && !TurkceMi(kullanici_yazi[i]))
                {
                    // Vigenere formülü için integer değişken oluşturuyorum
                    int formul;

                    // Karakter büyük harfse formül bu şekilde oluyor
                    if (char.IsUpper(kullanici_yazi[i]))
                    {
                        formul = ((kullanici_yazi[i] - 65) - (char.ToUpper(anahtar_kelime[anahtar_kelime_sayac % anahtar_kelime_length]) - 65)) % 26;
                        if (formul < 0)
                        {
                            formul += 26;
                        }

                        sifre_yazi += (char)(formul + 65);
                        anahtar_kelime_sayac++;
                    }
                    // Karakter küçük harfse formül bu şekilde oluyor
                    else
                    {
                        formul = ((kullanici_yazi[i] - 97) - (char.ToLower(anahtar_kelime[anahtar_kelime_sayac % anahtar_kelime_length]) - 97)) % 26;
                        if (formul < 0)
                        {
                            formul += 26;
                        }

                        sifre_yazi += (char)(formul + 97);
                        anahtar_kelime_sayac++;
                    }
                }
                // Eğer karakterler harf değilse ve Türkçe ise, olduğu gibi sifre_yazi değişkenine aktarılıyor
                else
                {
                    sifre_yazi += kullanici_yazi[i];
                }
            }

            // Deşifre edilmiş yazıyı gönderiyorum
            return sifre_yazi;
        }
    }
}

Vigenere Şifreleme Ekranının Kodları

Şifreleme ekranının kodlarını Github’da incelemek için tıklayın.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VigenereCipher
{
    public partial class VigenereSifreleme : Form
    {
        // Program açıldığında ilk burası çalışıyor
        public VigenereSifreleme()
        {
            InitializeComponent();

            // Program açıldığında hızlıca yazmaya başlamak için en üstteki textbox'ı seçiyorum
            txtAnahtarKelime.Select();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Eğer textbox'lar boş değilse program başlıyor
            if (txtAnahtarKelime.Text != "" && txtYaziSifre.Text != "")
            {
                // Yazdığım sınıftan bir nesne oluşturuyorum.
                VigenereCipher vigenere = new VigenereCipher(txtAnahtarKelime.Text, txtYaziSifre.Text);

                // Anahtar kelimenin sadece İngilizce karakterler içerip içermediğine bakıyorum. Sorun varsa uyarı mesajı yazdırıyorum
                if (vigenere.AnahtarKelimeAlfabetikMi())
                {
                    // Nesnenin "Sifrele" metodunu kullanarak yazıyı şifreliyorum ve textbox'a yazdırıyorum.
                    txtSifrelenenYazi.Text = vigenere.Sifrele();
                }
                else
                {
                    MessageBox.Show("Lütfen anahtar kelimeye İngilizce karakter dışında birşey girmeyiniz.");
                }
            }

            // Eğer kutular boşsa ekrana uyarı mesajı yazdırıyorum
            else
            {
                MessageBox.Show("Lütfen kutuları boş bırakmayınız.");
            }
        }

        // "Temizle" butonuna basılınca tüm textbox'ların içini temizliyorum
        private void button2_Click(object sender, EventArgs e)
        {
            txtAnahtarKelime.Clear();
            txtYaziSifre.Clear();
            txtSifrelenenYazi.Clear();
        }

        // Menüde "Şifre Çöz"e tıklanırsa, bu formu gizleyip 2. formu (Şifre Çöz) gösteriyorum
        private void şifreÇözToolStripMenuItem_Click(object sender, EventArgs e)
        {
            VigenereSifreCozucu form2 = new VigenereSifreCozucu();
            this.Visible = false;
            form2.Show();
        }

        // "Programdan Çık" yazısına tıklanınca program kapanıyor
        private void programdanÇıkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Vigenere Deşifre Ekranının Kodları

Şifreleme ekranından tek farkı, “Sifrele” metodu yerine “DesifreEt” metodunu kullanmam.

Deşifre ekranının kodlarını Github’da incelemek için tıklayın.

// Yazdığım sınıftan bir nesne oluşturuyorum.
VigenereCipher vigenere = new VigenereCipher(txtAnahtarKelime.Text, txtYaziSifre.Text);

// Anahtar kelimenin sadece İngilizce karakterler içerip içermediğine bakıyorum. Sorun varsa uyarı mesajı yazdırıyorum
if (vigenere.AnahtarKelimeAlfabetikMi())
{
    // Nesnenin "Sifrele" metodunu kullanarak yazıyı şifreliyorum ve textbox'a yazdırıyorum.
    txtDesifreEdilenYazi.Text = vigenere.DesifreEt();
}
else
{
    MessageBox.Show("Lütfen anahtar kelimeye İngilizce karakter dışında birşey girmeyiniz.");
}

Yararlandığım Kaynaklar

  1. Şifreler Kitabı – Paul Lunde
  2. Harvard CS50 – Introduction to Computer Science

Uygulamayı indirmek için tıklayın (VigenereCipher adlı klasör) => Github

Sezar şifreleme uygulaması yazımı incelemek için tıklayın => Sezar Şifreleme Uygulaması (C#)

Diğer yazılarımı incelemek için tıklayın => Erdi Uçar

“Vigenere Şifreleme Programı (C#)” üzerine 2 yorum

Bir Cevap Yazın