Advertisement
Fel1x

Keyed caesar

Feb 6th, 2024
1,311
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.68 KB | Source Code | 0 0
  1. open Printf
  2.  
  3. module Alphabets = struct
  4.   (*let original_latin_alphabet = "ABCDEFZHIKLMNOPQRSTVX"*)
  5.   (*let old_latin_alphabet = "ABCDEFGHIKLMNOPQRSTVX"*)
  6.   let classical_latin_alphabet = "ABCDEFGHIKLMNOPQRSTVXYZ"
  7.   (*let modern_latin_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"*)
  8. end
  9.  
  10. let deduplicate str =
  11.   let result = Buffer.create (String.length str) in
  12.   let tbl = Hashtbl.create (String.length str) in
  13.   String.iter (
  14.     fun c ->
  15.       if not (Hashtbl.mem tbl c) then begin
  16.         Buffer.add_char result c;
  17.         Hashtbl.add tbl c ();
  18.       end
  19.   ) str;
  20.   Buffer.contents result
  21.  
  22. let filter_string s f =
  23.   let buf = Buffer.create (String.length s) in
  24.   String.iter (fun c -> if f c then Buffer.add_char buf c) s;
  25.   Buffer.contents buf
  26.  
  27. let keyed_alphabet keyword alphabet =
  28.   let dedup_keyword = deduplicate (String.uppercase_ascii keyword) in
  29.   let alpha_minus_keyword =
  30.     filter_string alphabet (fun c -> not (String.contains dedup_keyword c))
  31.   in
  32.   dedup_keyword ^ alpha_minus_keyword
  33.  
  34. let caesar_encode keyed_alphabet shift text =
  35.   let shift_mod = shift mod String.length keyed_alphabet in
  36.   let find_index c =
  37.     try Some (String.index keyed_alphabet c)
  38.     with Not_found -> None
  39.   in
  40.   let shift_char c =
  41.     match find_index c with
  42.     | Some index ->
  43.         keyed_alphabet.[(index + shift_mod) mod String.length keyed_alphabet]
  44.     | None -> c
  45.   in
  46.   String.map shift_char text
  47.  
  48. let caesar_decode keyed_alphabet shift text =
  49.   let shift_mod = shift mod String.length keyed_alphabet in
  50.   let find_index c =
  51.     try Some (String.index keyed_alphabet c)
  52.     with Not_found -> None
  53.   in
  54.   let shift_char c =
  55.     match find_index c with
  56.     | Some index ->
  57.         let shifted_index = (index - shift_mod) mod String.length keyed_alphabet in
  58.         let corrected_index =
  59.           if shifted_index < 0
  60.             then shifted_index + String.length keyed_alphabet
  61.           else
  62.             shifted_index in
  63.               keyed_alphabet.[corrected_index]
  64.     | None -> c
  65.   in
  66.   String.map shift_char text
  67.  
  68. let () =
  69.   let keyword = "helo" in
  70.   let text_to_encrypt = "HELLO, WORLD!" in
  71.   let shift = 13 in (* Shift by 13, as in the standard Caesar cipher *)
  72.   let keyed_alpha = keyed_alphabet keyword Alphabets.classical_latin_alphabet in
  73.   let encrypted_text = caesar_encode keyed_alpha shift text_to_encrypt in
  74.   let decrypted_text = caesar_decode keyed_alpha shift encrypted_text in
  75.  
  76.   printf "Original text: %s\n" text_to_encrypt;
  77.   printf "Keyword: %s\n" keyword;
  78.   printf "Keyed alphabet: %s\n" keyed_alpha;
  79.   printf "Shifted by: %d\n" shift;
  80.   printf "Encrypted text: %s\n" encrypted_text;
  81.   printf "Decrypted text: %s\n" decrypted_text
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement