From b1ed92ffd759e9f0ca07aaa6658cf275779c6cfc Mon Sep 17 00:00:00 2001 From: AnnaEf24 <44416169+AnnaEf24@users.noreply.github.com> Date: Thu, 7 Apr 2022 19:08:07 +0300 Subject: [PATCH 1/5] File added --- encryption.py | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 encryption.py diff --git a/encryption.py b/encryption.py new file mode 100644 index 0000000..30612cb --- /dev/null +++ b/encryption.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 +import os +import random +import click + +#alphabets +alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' +alphabet_vig = 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ >= len_key): + iter = 0 + return dic + +def full_encode(value, key, lang): + dic = comparator(value, key) + lis = [] + d = form_dict(lang) + + for v in dic: + go = (dic[v][0]+dic[v][1]) % len(d) + lis.append(go) + return lis + +def decode_val(list_in, lang): + list_code = [] + lent = len(list_in) + d = form_dict(lang) + count=0 + for i in range(lent): + for value in d: + if list_in[i] == value: + list_code.append(d[value]) + return list_code + +def full_decode(value, key, lang): + dic = comparator(value, key) + d = form_dict(lang) + lis =[] + + for v in dic: + go = (dic[v][0]-dic[v][1]+len(d)) % len(d) + lis.append(go) + return lis + +def Vigenere_cipher(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r', encoding = 'utf-8') as f: + text = f.read().upper() + key = input('Enter the key value (word): ') + keyf = open('Vigenere_key.txt', 'w') + keyf.write(key) + key_encoded = encode_val(key.upper(), lang) + value_encoded = encode_val(text, lang) + shifre = full_encode(value_encoded, key_encoded, lang) + result = decode_val(shifre, lang) + decoded = full_decode(shifre, key_encoded, lang) + + res = open('Vigenere_encryption.txt', 'w') + res.write(''.join(result)) + + #in case you wanted to explore the process: + #print ('Value: ', value_encoded) + #print ('Key: ', key_encoded) + #print ('Decode list:', decoded) + print ('Cipher: ', ''.join(result)) + print ('Input text: ', text) + +def Vigenere_decipher(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r') as f: + text = f.read() + key = input('Enter the key value (word): ') + key_encoded = encode_val(key.upper(), lang) + shifre = encode_val(text, lang) + decoded = full_decode(shifre, key_encoded, lang) + result = ''.join(decode_val(decoded, lang)) + res = open('Vigenere_decoding.txt', 'w') + res.write(''.join(result)) + print ('Dechipher: ', result) + print ('Input text: ', text) + +def Vernam_cipher(input_file): + with open(input_file, 'rb') as inf: + keyf = open('Vernam_key.txt', 'wb') + outf = open('Vernam_encryption.txt', 'wb') + byte_in = inf.read(1) + while byte_in: + new_key = random.randint(0, 255) + new_byte = bytes([ord(byte_in) ^ new_key]) + outf.write(new_byte) + keyf.write(bytes([new_key])) + byte_in = inf.read(1) + +def Vernam_decipher(input_file): + with open(input_file, 'rb') as inf: + key = input('Enter the key file (path)): ') + keyf = open(key, 'rb') + outf = open('Vernam_decoding.txt', 'wb') + byte_in = inf.read(1) + while byte_in: + new_key = keyf.read(1) + new_byte = bytes([ord(new_key) ^ ord(byte_in)]) + outf.write(new_byte) + byte_in = inf.read(1) + +def Caesar_analysis(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r') as f: + text = f.read().upper() + + if lang == "BOTH": + alpha=alphabet + if lang == "RU": + alpha=alphabet_RU + if lang == "EU": + alpha=alphabet_EU + ma = 0 + index = 0 + text_ind = 0 + for i in range(len(alpha)): + count = 0 + for p in range(len(text)): + if alpha[i] == text[p]: + count += 1 + if ma < count: + ma = count + index = i + 1 + text_ind = p + if lang == "RU": + shift = abs(16 - index) + elif lang == "EU": + shift = abs(5 - index) + else: + count = 0 + for i in range(len(alphabet_EU)): + if text[p] == alphabet_EU[i]: + count = 1 + shift = abs(5 - index) + if count == 0: + shift = abs(42 - index) + result = '' + for i in text: + place = alpha.find(i) + new_place = (place - shift) % len(alpha) + if i in alphabet: + result += alpha[new_place] + else: + result += i + + print('Decipher:', result) + print('Input text: ', text) + res = open('Caesar_decoding.txt', 'w') + res.write(result) + +@click.command() +@click.option("--cipher", type=str, + help="Use one of: Caesar_cipher, Caesar_decipher, Vigenere_cipher, Vigenere_decipher, Vernam_cipher, Vernam_decipher, Caesar_analysis") +@click.option("--input_file", type=click.Path(exists=True, file_okay=True), required=True, + help="Source of input file") +def main(cipher, input_file): + if cipher == 'Caesar_cipher': + Caesar_cipher(input_file) + if cipher == 'Caesar_decipher': + Caesar_decipher(input_file) + if cipher == 'Vigenere_cipher': + Vigenere_cipher(input_file) + if cipher == 'Vigenere_decipher': + Vigenere_decipher(input_file) + if cipher == 'Vernam_cipher': + Vernam_cipher(input_file) + with open('Vernam_encryption.txt', 'r') as file: + print('Cipher: ', file.read()) + with open(input_file, 'r', encoding = 'utf-8') as file: + print('Input_text: ', file.read()) + if cipher == 'Vernam_decipher': + Vernam_decipher(input_file) + with open('Vernam_decoding.txt', 'r', encoding = 'utf-8') as file: + print('Decipher: ', file.read()) + with open(input_file, 'r') as file: + print('Input_text: ', file.read()) + if cipher == 'Caesar_analysis': + Caesar_analysis(input_file) + +if __name__ == "__main__": + main() + From 67c0ab2157be89f52a86d15f24495532594ac1de Mon Sep 17 00:00:00 2001 From: Annarrchy <91114932+Annarrchy@users.noreply.github.com> Date: Thu, 7 Apr 2022 20:49:38 +0300 Subject: [PATCH 2/5] Update README.md --- README.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6e4078..2f4bc50 100644 --- a/README.md +++ b/README.md @@ -1 +1,66 @@ -# Python-Efimova-121 \ No newline at end of file +# Шифровщик +Проект представляет собой программу, написанную на языке программирования Python, которая умеет шифровать и дешифровать текст разными методами. +При исполнении программа выводит шированный/дешифрованный текст и исходный в командную строку, а также создает файл, куда записывает результат. (Caesar_encryption.txt, Vigenere_encryption.txt, Vernam_encryption.txt) +Кроме этого при шифровании создается еще 1 файл: для шифра Цезаря - со значением сдвига шифрования, для Виженера и Вернама- со значением ключа. (Caesar_key.txt, Vigenere_key.txt, Vernam_key.txt) +## Функционал: ++ #### Шифрование шифрами: + + Цезаря + + Виженера + + Вернама ++ #### Дешифрование представленных шифров ++ #### Дешифрование шифра цезаря методом частотного анализа ++ #### Выбор языка (русский, английский или оба) ++ #### Вызов из командной строки, выбор режима с помощью ее аргументов +## Режимы работы +У скрипта есть 7 режимов работы. Для каждого в командной строке нужно ввести 2 аргумента: ++ --cipher - режим работы программы. Один из: Caesar_cipher, Caesar_decipher, Vigenere_cipher, Vigenere_decipher, Vernam_cipher, Vernam_decipher, Caesar_analysis. ++ --input_file - путь к исходному текстовому файлу, который нужно шифровать/дешифровать. +##### Пример: +``` +$ python encryption.py --cipher=Caesar_cipher --input_file=file.txt +``` +#### Caesar_cipher/Caesar_decipher - Шифр Цезаря +При выборе потребуется ввести выбранный язык и значение сдвига: +![image](https://user-images.githubusercontent.com/91114932/162256571-fd2160ca-bec1-414f-ab2a-d5f4c2163159.png) +#### Vigenere_cipher/Vigenere_decipher - Шифр Виженера +При выборе потребуется ввести выбранный язык и значение ключа (он должен быть на выбранном языке): +![image](https://user-images.githubusercontent.com/91114932/162257502-e50dcf53-2702-4cb3-99b5-440364f2eb93.png) +#### Vernam_cipher/Vernam_decipher - Шифр Вернама +Для шифровки ничего вводить не потребуется (языки шифруются одинаково, ключ создается сам случайно). +Для дешифровки потребуется также ввести путь к файлу с ключом: +![image](https://user-images.githubusercontent.com/91114932/162258363-94b5dbda-8d82-4dd6-8786-3d1da2abd062.png) +#### Caesar_analysis - Дешифрование шифра цезаря методом частотного анализа +Ничего вводить не потребуется. +Важно помнить, что этот метод дешифрования работает только на больших текстах (ниже описывается, почему). +Рекомендуется для примера использовать следующий: +> шерлок холмс - литературный персонаж, созданный артуром конан дойлом. его произведения, посвящённые приключениям шерлока холмса, знаменитого лондонского частного детектива, считаются классикой детективного жанра. +## Описание алгоритмов +#### Шифр Цезаря +Это тип шифра подстановочного типа, где каждая буква в открытом тексте заменяется на другую букву, смещенную на некоторое фиксированное количество (сдвиг) позиций в алфавите. +#### Шифр Виженера +Метод является усовершенствованным шифром Цезаря, где буквы смещались на определенную позицию. +Шифр Виженера состоит из последовательности нескольких шифров Цезаря с различными значениями сдвига. + +Допустим у нас есть некий алфавит, где каждой букве соответствуют цифры: +![vig1](https://user-images.githubusercontent.com/91114932/162260498-df8897f3-7acf-4ce4-a505-eab953d570c0.png) +Тогда если буквы a-z соответствуют числам 0-25, то шифрование Виженера можно записать в виде формулы: +![vig2](https://user-images.githubusercontent.com/91114932/162260559-4721f9d1-d1d4-43f6-90bf-cb80fe64f82b.png) +#### Шифр Вернама +Для получения шифротекста открытый текст объединяется операцией «исключающее или» с секретным ключом. + +Для каждого байта входного файла генерируется случайный байт, который записывается в отдельный файл-ключ. Далее вычисляется побитовое исключающее ИЛИ (XOR) для этих двух байтов и записывается в выходной файл. +Пример: +![image](https://user-images.githubusercontent.com/91114932/162260898-16de9c6e-92eb-4ca3-afb0-2db917fbcd54.png) +#### Дешифрование шифра цезаря методом частотного анализа +Частотный анализ - один из методов дешифровки, он заключается в том, что для каждой буквы алфавита, есть усредненная частота появления в тексте. +В русском языке наиболее часто встречающейся буквой, с точки зрения статистики, является буква "о", с частотой 10,983. В английском языке это буква e. + +Обратите внимание, что частотный анализ будет прекрасно работать на шифротекстах, стостоящих из примерно десятка слов и более. Чем короче шифротекст, тем больше вероятность, что такой подход даст сбой. + +В чем заключается суть алгоритма дешифрования: +1. Запрашиваем исходный текст +2. Находим средние частоты появления каждой буквы +3. Находим букву с наибольшей частотой (например "г") +4. Априорно считаем эту букву буквой "о" (или "e", в зависимости от языка) +5. Зная местоположения в алфавите букв "о" и "г" определяем сдвиг +6. Расшифровываем текст, используя полученный ключ From 52ca949964b441522088853ade5d9efaba90bbbf Mon Sep 17 00:00:00 2001 From: Annarrchy <91114932+Annarrchy@users.noreply.github.com> Date: Thu, 7 Apr 2022 21:06:31 +0300 Subject: [PATCH 3/5] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2f4bc50..3f94f6c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Шифровщик Проект представляет собой программу, написанную на языке программирования Python, которая умеет шифровать и дешифровать текст разными методами. +Необходимы библиотеки: os, random, click. При исполнении программа выводит шированный/дешифрованный текст и исходный в командную строку, а также создает файл, куда записывает результат. (Caesar_encryption.txt, Vigenere_encryption.txt, Vernam_encryption.txt) Кроме этого при шифровании создается еще 1 файл: для шифра Цезаря - со значением сдвига шифрования, для Виженера и Вернама- со значением ключа. (Caesar_key.txt, Vigenere_key.txt, Vernam_key.txt) ## Функционал: From 44a3f7ed53fd0b1cee4074ceb070dad777f3ab31 Mon Sep 17 00:00:00 2001 From: AnnaEf24 <44416169+AnnaEf24@users.noreply.github.com> Date: Fri, 22 Apr 2022 00:40:56 +0300 Subject: [PATCH 4/5] Project fixed --- encryption.py | 286 ------------------------------------ encryption/alphabet.py | 7 + encryption/caesar_an.py | 71 +++++++++ encryption/caesar_ciph.py | 60 ++++++++ encryption/encryption.py | 43 ++++++ encryption/file.txt | 4 + encryption/vernam_ciph.py | 26 ++++ encryption/vigenere_ciph.py | 111 ++++++++++++++ 8 files changed, 322 insertions(+), 286 deletions(-) delete mode 100644 encryption.py create mode 100644 encryption/alphabet.py create mode 100644 encryption/caesar_an.py create mode 100644 encryption/caesar_ciph.py create mode 100644 encryption/encryption.py create mode 100644 encryption/file.txt create mode 100644 encryption/vernam_ciph.py create mode 100644 encryption/vigenere_ciph.py diff --git a/encryption.py b/encryption.py deleted file mode 100644 index 30612cb..0000000 --- a/encryption.py +++ /dev/null @@ -1,286 +0,0 @@ -#!/usr/bin/env python3 -import os -import random -import click - -#alphabets -alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' -alphabet_vig = 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ >= len_key): - iter = 0 - return dic - -def full_encode(value, key, lang): - dic = comparator(value, key) - lis = [] - d = form_dict(lang) - - for v in dic: - go = (dic[v][0]+dic[v][1]) % len(d) - lis.append(go) - return lis - -def decode_val(list_in, lang): - list_code = [] - lent = len(list_in) - d = form_dict(lang) - count=0 - for i in range(lent): - for value in d: - if list_in[i] == value: - list_code.append(d[value]) - return list_code - -def full_decode(value, key, lang): - dic = comparator(value, key) - d = form_dict(lang) - lis =[] - - for v in dic: - go = (dic[v][0]-dic[v][1]+len(d)) % len(d) - lis.append(go) - return lis - -def Vigenere_cipher(input_file): - lang = input('Choose language: RU/EU/BOTH: ') - with open(input_file, 'r', encoding = 'utf-8') as f: - text = f.read().upper() - key = input('Enter the key value (word): ') - keyf = open('Vigenere_key.txt', 'w') - keyf.write(key) - key_encoded = encode_val(key.upper(), lang) - value_encoded = encode_val(text, lang) - shifre = full_encode(value_encoded, key_encoded, lang) - result = decode_val(shifre, lang) - decoded = full_decode(shifre, key_encoded, lang) - - res = open('Vigenere_encryption.txt', 'w') - res.write(''.join(result)) - - #in case you wanted to explore the process: - #print ('Value: ', value_encoded) - #print ('Key: ', key_encoded) - #print ('Decode list:', decoded) - print ('Cipher: ', ''.join(result)) - print ('Input text: ', text) - -def Vigenere_decipher(input_file): - lang = input('Choose language: RU/EU/BOTH: ') - with open(input_file, 'r') as f: - text = f.read() - key = input('Enter the key value (word): ') - key_encoded = encode_val(key.upper(), lang) - shifre = encode_val(text, lang) - decoded = full_decode(shifre, key_encoded, lang) - result = ''.join(decode_val(decoded, lang)) - res = open('Vigenere_decoding.txt', 'w') - res.write(''.join(result)) - print ('Dechipher: ', result) - print ('Input text: ', text) - -def Vernam_cipher(input_file): - with open(input_file, 'rb') as inf: - keyf = open('Vernam_key.txt', 'wb') - outf = open('Vernam_encryption.txt', 'wb') - byte_in = inf.read(1) - while byte_in: - new_key = random.randint(0, 255) - new_byte = bytes([ord(byte_in) ^ new_key]) - outf.write(new_byte) - keyf.write(bytes([new_key])) - byte_in = inf.read(1) - -def Vernam_decipher(input_file): - with open(input_file, 'rb') as inf: - key = input('Enter the key file (path)): ') - keyf = open(key, 'rb') - outf = open('Vernam_decoding.txt', 'wb') - byte_in = inf.read(1) - while byte_in: - new_key = keyf.read(1) - new_byte = bytes([ord(new_key) ^ ord(byte_in)]) - outf.write(new_byte) - byte_in = inf.read(1) - -def Caesar_analysis(input_file): - lang = input('Choose language: RU/EU/BOTH: ') - with open(input_file, 'r') as f: - text = f.read().upper() - - if lang == "BOTH": - alpha=alphabet - if lang == "RU": - alpha=alphabet_RU - if lang == "EU": - alpha=alphabet_EU - ma = 0 - index = 0 - text_ind = 0 - for i in range(len(alpha)): - count = 0 - for p in range(len(text)): - if alpha[i] == text[p]: - count += 1 - if ma < count: - ma = count - index = i + 1 - text_ind = p - if lang == "RU": - shift = abs(16 - index) - elif lang == "EU": - shift = abs(5 - index) - else: - count = 0 - for i in range(len(alphabet_EU)): - if text[p] == alphabet_EU[i]: - count = 1 - shift = abs(5 - index) - if count == 0: - shift = abs(42 - index) - result = '' - for i in text: - place = alpha.find(i) - new_place = (place - shift) % len(alpha) - if i in alphabet: - result += alpha[new_place] - else: - result += i - - print('Decipher:', result) - print('Input text: ', text) - res = open('Caesar_decoding.txt', 'w') - res.write(result) - -@click.command() -@click.option("--cipher", type=str, - help="Use one of: Caesar_cipher, Caesar_decipher, Vigenere_cipher, Vigenere_decipher, Vernam_cipher, Vernam_decipher, Caesar_analysis") -@click.option("--input_file", type=click.Path(exists=True, file_okay=True), required=True, - help="Source of input file") -def main(cipher, input_file): - if cipher == 'Caesar_cipher': - Caesar_cipher(input_file) - if cipher == 'Caesar_decipher': - Caesar_decipher(input_file) - if cipher == 'Vigenere_cipher': - Vigenere_cipher(input_file) - if cipher == 'Vigenere_decipher': - Vigenere_decipher(input_file) - if cipher == 'Vernam_cipher': - Vernam_cipher(input_file) - with open('Vernam_encryption.txt', 'r') as file: - print('Cipher: ', file.read()) - with open(input_file, 'r', encoding = 'utf-8') as file: - print('Input_text: ', file.read()) - if cipher == 'Vernam_decipher': - Vernam_decipher(input_file) - with open('Vernam_decoding.txt', 'r', encoding = 'utf-8') as file: - print('Decipher: ', file.read()) - with open(input_file, 'r') as file: - print('Input_text: ', file.read()) - if cipher == 'Caesar_analysis': - Caesar_analysis(input_file) - -if __name__ == "__main__": - main() - diff --git a/encryption/alphabet.py b/encryption/alphabet.py new file mode 100644 index 0000000..4b0677b --- /dev/null +++ b/encryption/alphabet.py @@ -0,0 +1,7 @@ +#alphabets +alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' +alphabet_vig = 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ > len(alphabet_RU): + enru = True + for i in text: + if i == ' ': + space += 1 + elif i in alpha: + rate[ord_alpha[i]] += 1 + rate = list(map(lambda x: x / (len(text) - space), rate)) + shifts = {i : 0 for i in range(len(ord_alpha))} + for i in range(len(ord_alpha)): + diff = 1 + sdv = 0 + for p in range(len(ord_alpha)): + if diff > abs(rate[i] - rate_al[p]): + if (enru == False) or (enru and ((i < 26 and p < 26) or (i > 25 and p > 25))): + diff = abs(rate[i] - rate_al[p]) + sdv = p + if i > sdv: + sdv = i - sdv + elif i < sdv: + sdv = len(alpha) - sdv + i + shifts[sdv] += 1 + + shift = sorted(list(shifts.keys()), key=lambda x: shifts[x])[-1] + return shift + + + + +def caesar_analysis(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r') as f: + text = f.read().upper() + + if lang == "BOTH": + alpha = alphabet + rate_al = rate_BOTH + if lang == "RU": + alpha=alphabet_RU + rate_al = rate_RU + if lang == "EU": + alpha=alphabet_EU + rate_al = rate_EU + ord_alpha = {} + for i in range(len(alpha)): + ord_alpha[alpha[i]] = i + + shift = find_shift(text, ord_alpha, rate_al, alpha) + result = '' + for i in text: + place = alpha.find(i) + new_place = (place - shift) % len(alpha) + if i in alphabet: + result += alpha[new_place] + else: + result += i + + print('Decipher:', result) + print('Input text: ', text) + res = open('Caesar_decoding.txt', 'w') + res.write(result) diff --git a/encryption/caesar_ciph.py b/encryption/caesar_ciph.py new file mode 100644 index 0000000..bb66b20 --- /dev/null +++ b/encryption/caesar_ciph.py @@ -0,0 +1,60 @@ +from alphabet import * + +def caesar_cipher(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r', encoding = 'utf-8') as f: + text = f.read().upper() + #key of encryption + shift = int(input('Enter the shift value (number)): ')) + keyf = open('Caesar_key.txt', 'w') + keyf.write(str(shift)) + result = '' + alpha = '' + if lang == "BOTH": + alpha=alphabet + if lang == "RU": + alpha=alphabet_RU + if lang == "EU": + alpha=alphabet_EU + + for i in text: + place = alpha.find(i) + new_place = (place + shift) % len(alpha) + if i in alphabet: + result += alpha[new_place] + else: + result += i + + print('Cipher:', result) + print('Input text: ', text) + res = open('Caesar_encryption.txt', 'w') + res.write(result) + +def caesar_decipher(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r') as f: + text = f.read().upper() + + shift = int(input('Enter the shift value (number)): ')) + result = '' + alpha = '' + if lang == "BOTH": + alpha=alphabet + if lang == "RU": + alpha=alphabet_RU + if lang == "EU": + alpha=alphabet_EU + + for i in text: + place = alpha.find(i) + new_place = (place - shift) % len(alpha) + if i in alphabet: + result += alpha[new_place] + else: + result += i + + print('Decipher:', result) + print('Input text: ', text) + res = open('Caesar_decoding.txt', 'w') + res.write(result) + diff --git a/encryption/encryption.py b/encryption/encryption.py new file mode 100644 index 0000000..95a537f --- /dev/null +++ b/encryption/encryption.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import random +import click +import caesar_ciph +import vigenere_ciph +import vernam_ciph +import caesar_an + +@click.command() +@click.option("--cipher", "-c", type=str, + help="Use one of: Caesar_cipher (cac), Caesar_decipher (cad), Vigenere_cipher (vic), Vigenere_decipher (vid), Vernam_cipher (vec), Vernam_decipher (ved), Caesar_analysis (can)") +@click.option("--input_file", "-i", type=click.Path(exists=True, file_okay=True), required=True, + help="Source of input file") +def main(cipher, input_file): + if cipher == 'Caesar_cipher' or cipher == 'cac': + caesar_ciph.caesar_cipher(input_file) + if cipher == 'Caesar_decipher' or cipher == 'cad': + caesar_ciph.caesar_decipher(input_file) + if cipher == 'Vigenere_cipher' or cipher == 'vic': + vigenere_ciph.vigenere_cipher(input_file) + if cipher == 'Vigenere_decipher' or cipher == 'vid': + vigenere_ciph.vigenere_decipher(input_file) + if cipher == 'Vernam_cipher' or cipher == 'vec': + vernam_ciph.vernam_cipher(input_file) + with open('Vernam_encryption.txt', 'r', encoding = 'Latin-1') as file: + print('Cipher: ', file.read()) + with open(input_file, 'r', encoding = 'utf-8') as file: + print('Input_text: ', file.read()) + if cipher == 'Vernam_decipher' or cipher == 'ved': + vernam_ciph.vernam_decipher(input_file) + with open('Vernam_decoding.txt', 'r', encoding = 'utf-8') as file: + print('Decipher: ', file.read()) + with open(input_file, 'r', encoding = 'Latin-1') as file: + print('Input_text: ', file.read()) + if cipher == 'Caesar_analysis' or cipher == 'can': + caesar_an.caesar_analysis(input_file) + +if __name__ == "__main__": + main() + diff --git a/encryption/file.txt b/encryption/file.txt new file mode 100644 index 0000000..f473b20 --- /dev/null +++ b/encryption/file.txt @@ -0,0 +1,4 @@ +Князь Василий говорил всегда лениво, как актер говорит роль старой пиесы. Анна Павловна Шерер, напротив, несмотря на свои сорок лет, была преисполнена оживления и порывов. +Быть энтузиасткой сделалось ее общественным положением, и иногда, когда ей даже того не хотелось, она, чтобы не обмануть ожиданий людей, знавших ее, делалась энтузиасткой. Сдержанная улыбка, игравшая постоянно на лице Анны Павловны, хотя и не шла к ее отжившим чертам, выражала, как у избалованных детей, постоянное сознание своего милого недостатка, от которого она не хочет, не может и не находит нужным исправляться. +В середине разговора про политические действия Анна Павловна разгорячилась. +— Ах, не говорите мне про Австрию! Я ничего не понимаю, может быть, но Австрия никогда не хотела и не хочет войны. Она предает нас. Россия одна должна быть спасительницей Европы. Наш благодетель знает свое высокое призвание и будет верен ему. Вот одно, во что я верю. Нашему доброму и чудному государю предстоит величайшая роль в мире, и он так добродетелен и хорош, что Бог не оставит его, и он исполнит свое призвание задавить гидру революции, которая теперь еще ужаснее в лице этого убийцы и злодея. Мы одни должны искупить кровь праведника. На кого нам надеяться, я вас спрашиваю.. Англия с своим коммерческим духом не поймет и не может понять всю высоту души императора Александра. Она отказалась очистить Мальту. Она хочет видеть, ищет заднюю мысль наших действий. Что они сказали Новосильцеву Ничего. Они не поняли, они не могли понять самоотвержения нашего императора, который ничего не хочет для себя и все хочет для блага мира. И что они обещали Ничего. И что обещали, и того не будет! Пруссия уже объявила, что Бонапарте непобедим и что вся Европа ничего не может против него.. \ No newline at end of file diff --git a/encryption/vernam_ciph.py b/encryption/vernam_ciph.py new file mode 100644 index 0000000..c4fa2c6 --- /dev/null +++ b/encryption/vernam_ciph.py @@ -0,0 +1,26 @@ +import random +from alphabet import * + +def vernam_cipher(input_file): + with open(input_file, 'rb') as inf: + keyf = open('Vernam_key.txt', 'wb') + outf = open('Vernam_encryption.txt', 'wb') + byte_in = inf.read(1) + while byte_in: + new_key = random.randint(0, 255) + new_byte = bytes([ord(byte_in) ^ new_key]) + outf.write(new_byte) + keyf.write(bytes([new_key])) + byte_in = inf.read(1) + +def vernam_decipher(input_file): + with open(input_file, 'rb') as inf: + key = input('Enter the key file (path)): ') + keyf = open(key, 'rb') + outf = open('Vernam_decoding.txt', 'wb') + byte_in = inf.read(1) + while byte_in: + new_key = keyf.read(1) + new_byte = bytes([ord(new_key) ^ ord(byte_in)]) + outf.write(new_byte) + byte_in = inf.read(1) diff --git a/encryption/vigenere_ciph.py b/encryption/vigenere_ciph.py new file mode 100644 index 0000000..1114be5 --- /dev/null +++ b/encryption/vigenere_ciph.py @@ -0,0 +1,111 @@ +from alphabet import * + +def form_dict(lang): + d = {} + iter = 0 + + alphab = '' + if lang == "BOTH": + alphab = alphabet_vig + if lang == "RU": + alphab = alphabet_vigru + if lang == "EU": + alphab = alphabet_vigeu + + for i in alphab: + d[iter] = i + iter = iter + 1 + return d + +def encode_val(word, lang): + list_code = [] + lent = len(word) + d = form_dict(lang) + + for w in range(lent): + for value in d: + if word[w] == d[value]: + list_code.append(value) + return list_code + +def comparator(value, key): + len_key = len(key) + dic = {} + iter = 0 + full = 0 + + for i in value: + dic[full] = [i,key[iter]] + full = full + 1 + iter = iter +1 + if (iter >= len_key): + iter = 0 + return dic + +def full_encode(value, key, lang): + dic = comparator(value, key) + lis = [] + d = form_dict(lang) + + for v in dic: + go = (dic[v][0]+dic[v][1]) % len(d) + lis.append(go) + return lis + +def decode_val(list_in, lang): + list_code = [] + lent = len(list_in) + d = form_dict(lang) + count=0 + for i in range(lent): + for value in d: + if list_in[i] == value: + list_code.append(d[value]) + return list_code + +def full_decode(value, key, lang): + dic = comparator(value, key) + d = form_dict(lang) + lis =[] + + for v in dic: + go = (dic[v][0]-dic[v][1]+len(d)) % len(d) + lis.append(go) + return lis + +def vigenere_cipher(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r', encoding = 'utf-8') as f: + text = f.read().upper() + key = input('Enter the key value (word): ') + keyf = open('Vigenere_key.txt', 'w') + keyf.write(key) + key_encoded = encode_val(key.upper(), lang) + value_encoded = encode_val(text, lang) + shifre = full_encode(value_encoded, key_encoded, lang) + result = decode_val(shifre, lang) + decoded = full_decode(shifre, key_encoded, lang) + + res = open('Vigenere_encryption.txt', 'w') + res.write(''.join(result)) + + #in case you wanted to explore the process: + #print ('Value: ', value_encoded) + #print ('Key: ', key_encoded) + #print ('Decode list:', decoded) + print ('Cipher: ', ''.join(result)) + print ('Input text: ', text) + +def vigenere_decipher(input_file): + lang = input('Choose language: RU/EU/BOTH: ') + with open(input_file, 'r') as f: + text = f.read() + key = input('Enter the key value (word): ') + key_encoded = encode_val(key.upper(), lang) + shifre = encode_val(text, lang) + decoded = full_decode(shifre, key_encoded, lang) + result = ''.join(decode_val(decoded, lang)) + res = open('Vigenere_decoding.txt', 'w') + res.write(''.join(result)) + print ('Dechipher: ', result) + print ('Input text: ', text) From 4df1ce3556485f1c0be618053285a43e59800156 Mon Sep 17 00:00:00 2001 From: Annarrchy <91114932+Annarrchy@users.noreply.github.com> Date: Fri, 22 Apr 2022 01:03:48 +0300 Subject: [PATCH 5/5] Update README.md --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3f94f6c..4fd28d0 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ + #### Вызов из командной строки, выбор режима с помощью ее аргументов ## Режимы работы У скрипта есть 7 режимов работы. Для каждого в командной строке нужно ввести 2 аргумента: -+ --cipher - режим работы программы. Один из: Caesar_cipher, Caesar_decipher, Vigenere_cipher, Vigenere_decipher, Vernam_cipher, Vernam_decipher, Caesar_analysis. -+ --input_file - путь к исходному текстовому файлу, который нужно шифровать/дешифровать. ++ --cipher (или -c) - режим работы программы. Один из: Caesar_cipher (или cac), Caesar_decipher (cad), Vigenere_cipher (vic), Vigenere_decipher (vid), Vernam_cipher (vec), Vernam_decipher (ved), Caesar_analysis (can). ++ --input_file (или -i) - путь к исходному текстовому файлу, который нужно шифровать/дешифровать. ##### Пример: ``` $ python encryption.py --cipher=Caesar_cipher --input_file=file.txt @@ -32,9 +32,10 @@ $ python encryption.py --cipher=Caesar_cipher --input_file=file.txt ![image](https://user-images.githubusercontent.com/91114932/162258363-94b5dbda-8d82-4dd6-8786-3d1da2abd062.png) #### Caesar_analysis - Дешифрование шифра цезаря методом частотного анализа Ничего вводить не потребуется. -Важно помнить, что этот метод дешифрования работает только на больших текстах (ниже описывается, почему). +Важно помнить, что этот метод дешифрования может работать не на всех текстах (ниже описывается, почему). Рекомендуется для примера использовать следующий: > шерлок холмс - литературный персонаж, созданный артуром конан дойлом. его произведения, посвящённые приключениям шерлока холмса, знаменитого лондонского частного детектива, считаются классикой детективного жанра. +Также в папке проекта находится file.txt, содержащий отрывок из произведения "Война и мир", который также рекомендуется использовать для проверки. ## Описание алгоритмов #### Шифр Цезаря Это тип шифра подстановочного типа, где каждая буква в открытом тексте заменяется на другую букву, смещенную на некоторое фиксированное количество (сдвиг) позиций в алфавите. @@ -54,14 +55,15 @@ $ python encryption.py --cipher=Caesar_cipher --input_file=file.txt ![image](https://user-images.githubusercontent.com/91114932/162260898-16de9c6e-92eb-4ca3-afb0-2db917fbcd54.png) #### Дешифрование шифра цезаря методом частотного анализа Частотный анализ - один из методов дешифровки, он заключается в том, что для каждой буквы алфавита, есть усредненная частота появления в тексте. -В русском языке наиболее часто встречающейся буквой, с точки зрения статистики, является буква "о", с частотой 10,983. В английском языке это буква e. +В русском языке наиболее часто встречающейся буквой, с точки зрения статистики, является буква "о", с частотой 10,983. В английском языке это буква e. +Заметим, что мы знаем усредненные частоты всех букв. Обратите внимание, что частотный анализ будет прекрасно работать на шифротекстах, стостоящих из примерно десятка слов и более. Чем короче шифротекст, тем больше вероятность, что такой подход даст сбой. В чем заключается суть алгоритма дешифрования: 1. Запрашиваем исходный текст 2. Находим средние частоты появления каждой буквы -3. Находим букву с наибольшей частотой (например "г") -4. Априорно считаем эту букву буквой "о" (или "e", в зависимости от языка) -5. Зная местоположения в алфавите букв "о" и "г" определяем сдвиг +3. Для каждой буквы находим ближайшую к ней по частоте букву алфавита +4. Зная местоположения в алфавите этих букв определяем сдвиг +5. После такой обработки всех букв находим значение сдвига, которое втретчалось чаще прочих, и считаем его итоговым 6. Расшифровываем текст, используя полученный ключ