Hoşgeldin Misafir

F# Dilini Tanıyalım: X0R Şifreleme/Çözme Uygulaması Yazalım

xS0N3R

23 Ağu 2020
5,429 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Merhaba,

Bugün bir farklılık olsun F# diline bakacağız.
Bu dilde .NET tabanlı OOP (Nesne Tabanlı Programlama) üzerine kurulu hızlı bir dil.
Bugünde basit bir proje ile dile bakış atacağız.

Modül Tanımlayalım;​

module XorSifreleme

Bu satır, programı bir modül olarak tanımlar.
F#'ta modüller kodu organize etmek için kullanılır.

Kütüphanelerimiz;​


open System
open System.IO
open System.Text

X0R Şifreleme Fonksiyonu​


C#:
let xorIslemi (metin: byte[]) (anahtar: byte[]) : byte[] =
    let sonuc = Array.zeroCreate metin.Length
    for i in 0 .. metin.Length - 1 do
        sonuc.[i] <- metin.[i] ^^^ anahtar.[i % anahtar.Length]
    sonuc

metin; Şifrelenecek ya da çözülecek dosya içeriği (byte dizisi)
anahtar; XOR işlemi için kullanılacak byte dizisi olarak veriyoruz.
Array.zeroCreate; Verilen uzunlukta sıfırlarla dolu bir byte dizisi oluşturur.

X0R işlemi için; metin. ^^^ anahtar.[i % anahtar.Length]


Dosya Okuma/Yazma​


C#:
let dosyaIsle (dosyaYolu: string) (anahtar: string) islemTuru =

Bu fonksiyon, dosyayı okuyup şifreler veya çözer.

Dosyayı okumak içini C# ile aynı olan File.ReadAllBytes veya File.ReadAllText kullanacağız.

C#:
let dosyaIcerik = File.ReadAllBytes(dosyaYolu)

Anahtarı Byte dizisine çevirelim;

C#:
let anahtarBytes = Encoding.UTF8.GetBytes(anahtar: string)

Anahtarın boş olup, olmadığına bakalım;

C#:
if anahtarBytes.Length = 0 then
    printfn "Hata: Anahtar boş olamaz"

Şifreleme işlemi için, parametreleri verelim;

C#:
let sonucBytes = xorIslemi dosyaIcerik anahtarBytes

İşlem türlerini belirleyelim, Şifreleme çözme vs.

C#:
let ciktiDosyaAdi =
    match islemTuru with
    | "sifrele" -> ...
    | "coz" -> ...
    | _ -> failwith "Geçersiz işlem türü"

Şifreli veriyi yeni dosyaya yazalım;

C#:
File.WriteAllBytes(ciktiDosyaAdi, sonucBytes)

Hata yönetimleri;

C#:
| :? FileNotFoundException -> ...
| :? IOException as ex -> ...
| ex -> ...

Kullanıcı Arayüzü​


C#:
let rec menu () =

rec ifadesi, fonksiyonun kendini tekrar çağırmasına izin veriyor, Menü seçenekleri; şifrele çöz çık
Giriş Noktası (Main)


C#:
[<EntryPoint>]
let main argv =
    printfn "x0r şifreleme uygulaması test"
    menu ()
    0

argv; Komut satırı argümanları (kullanılmıyor ama yazılması zorunlu)
menu (); Uygulama kullanıcı menüsünü başlatır
0; Başarılı çıkış kodu

Kodun tamamı;​


C#:
module XorSifreleme

open System
open System.IO
open System.Text
let xorIslemi (metin: byte[]) (anahtar: byte[]) : byte[] =
    let sonuc = Array.zeroCreate metin.Length
    for i in 0 .. metin.Length - 1 do
        sonuc.[i] <- metin.[i] ^^^ anahtar.[i % anahtar.Length]
    sonuc

let dosyaIsle (dosyaYolu: string) (anahtar: string) islemTuru =
    try
        let dosyaIcerik = File.ReadAllBytes(dosyaYolu)
        let anahtarBytes = Encoding.UTF8.GetBytes(anahtar: string)

        if anahtarBytes.Length = 0 then
            printfn "Hata: Anahtar boş olamaz!"
            None
        else
            let sonucBytes = xorIslemi dosyaIcerik anahtarBytes

            let ciktiDosyaAdi =
                match islemTuru with
                | "sifrele" -> Path.Combine(Path.GetDirectoryName(dosyaYolu), Path.GetFileNameWithoutExtension(dosyaYolu) + "_sifreli.txt")
                | "coz" -> Path.Combine(Path.GetDirectoryName(dosyaYolu), Path.GetFileNameWithoutExtension(dosyaYolu) + "_cozulmus.txt")
                | _ -> failwith "Geçersiz işlem türü"


            File.WriteAllBytes(ciktiDosyaAdi, sonucBytes)
            printfn "%s işlemi başarılı! Çıktı dosyası: %s" (if islemTuru = "sifrele" then "Şifreleme" else "Çözme") ciktiDosyaAdi
            Some ciktiDosyaAdi
    with
    | :? FileNotFoundException ->
        printfn "Hata: Dosya bulunamadı: %s" dosyaYolu
        None
    | :? IOException as ex ->
        printfn "Hata: Dosya işlemi sırasında bir hata oluştu: %s" ex.Message
        None
    | ex ->
        printfn "Hata: %s" ex.Message
        None


let rec menu () =


    printfn "\n xor sifreleme test"
    printfn "1. Dosyayı Şifrele"
    printfn "2. Dosyayı Çöz"
    printfn "3. Çıkış"
    printf "Seçiminiz (1-3): "

    match Console.ReadLine() with
    | "1" ->
        printf "Şifrelenecek dosyanın yolunu girin: "
        let dosyaYolu = Console.ReadLine()
        printf "Şifreleme anahtarını girin: "
        let anahtar = Console.ReadLine()
        dosyaIsle dosyaYolu anahtar "sifrele" |> ignore
        menu ()
    | "2" ->
        printf "Çözülecek dosyanın yolunu girin: "
        let dosyaYolu = Console.ReadLine()
        printf "Çözme anahtarını girin: "
        let anahtar = Console.ReadLine()
        dosyaIsle dosyaYolu anahtar "coz" |> ignore
        menu ()
    | "3" ->
        printfn "Uygulama kapatılıyor..."
    | _ ->
        printfn "Geçersiz seçim! Lütfen 1, 2 veya 3 girin."


        menu ()


[<EntryPoint>]
let main argv =
    printfn "x0r şifreleme uygulaması test"
    menu ()
    0

Programı Deneyelim;​


3ypbx61.png


4rtgkgc.png


7inkpid.png