Caesar Cipher Encryption Decryption Using Python
What is Caesar Cipher Cryptography
A Caesar cipher, also known as Caesar’s cipher, the shift cipher, Caesar’s code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence
Encryption
For instance, here is a Caesar cipher using a left rotation of three places, equivalent to a right shift of 23 (the shift parameter is used as the key): Plain A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Cipher X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
When encrypting, a person looks up each letter of the message in the «plain» line and writes down the corresponding letter in the «cipher» line. Plaintext: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
Ciphertext: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD In simple word
plain text = "hello" shift = 5 cipher text = "mjqqt" print output: "The encoded text is mjqqt"
Code For Encrypton
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n") text = input("Type your message:\n").lower() shift = int(input("Type the shift number:\n")) def encrypt(plain_text,shift_amount): cipher_text ="" for letter in plain_text: position = alphabet.index(letter) new_position = position +shift_amount if new_position > 25: new_position2 = new_position-26 new_letter2 = alphabet[new_position2] cipher_text += new_letter2 else: new_letter1 = alphabet[new_position] cipher_text += new_letter1 print(f"The encoded text is .") encrypt(plain_text = text,shift_amount = shift)
The condition checked for new_position > 25 because there is no alphabet after 25 [List starts from 0 so total element will be 25]. To get back to starting position once it crosses last element we have to check this condition.
Decryption
cipher text = "mjqqt" shift = 5 plain text = "hello" print output: "The encoded text is hello"
Code For Decrypton
def decrypt(cipher_text, shift_amount): plain_text = "" for letter in cipher_text: position = alphabet.index(letter) new_position = position - shift_amount plain_text += alphabet[new_position] print(f"The decoded text is ")
- Adding a logo.
- What if the user enters a shift that is greater than the number of letters in the alphabet?
- What happens if the user enters a number/symbol/space?
- Can you figure out a way to ask the user if they want to restart the cipher program?
I am adding the final code here with solution of all the query mentioned above. Its also optimized version of the Encryption and Decryption code mention above.
Final Code
logo = """ ,adPPYba, ,adPPYYba, ,adPPYba, ,adPPYba, ,adPPYYba, 8b,dPPYba, a8" "" "" `Y8 a8P_____88 I8[ "" "" `Y8 88P' "Y8 8b ,adPPPPP88 8PP""""""" `"Y8ba, ,adPPPPP88 88 "8a, ,aa 88, ,88 "8b, ,aa aa ]8I 88, ,88 88 `"Ybbd8"' `"8bbdP"Y8 `"Ybbd8"' `"YbbdP"' `"8bbdP"Y8 88 88 88 "" 88 88 ,adPPYba, 88 8b,dPPYba, 88,dPPYba, ,adPPYba, 8b,dPPYba, a8" "" 88 88P' "8a 88P' "8a a8P_____88 88P' "Y8 8b 88 88 d8 88 88 8PP""""""" 88 "8a, ,aa 88 88b, ,a8" 88 88 "8b, ,aa 88 `"Ybbd8"' 88 88`YbbdP"' 88 88 `"Ybbd8"' 88 88 88 """ print(logo) alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] def caesar(start_text, shift_amount, cipher_direction): end_text = "" if cipher_direction == "decode": shift_amount *= -1 for char in start_text: if char in alphabet: position = alphabet.index(char) new_position = position + shift_amount end_text += alphabet[new_position] else: end_text += char print(f"Here's the d result: ") should_end = False while not should_end: direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n") text = input("Type your message:\n").lower() shift = int(input("Type the shift number:\n")) shift = shift % 26 caesar(start_text=text, shift_amount=shift, cipher_direction=direction) restart = input("Type 'yes' if you want to go again. Otherwise type 'no'.\n") if restart == "no": should_end = True print("Goodbye")
In one program we are doing both encryption and decryption by asking the user. Please go through this and give it a like and comment what you think about the program and description provided.
If you want to see the details of my Python Bootcamp Programs and resources. Please go this below Github link and explore.
If you want to create any type ASCII word, Please go through the below link. I have generated that logo from this site.
Программа: «Примитивный шифратор-дешифратор»
Задание: необходимо написать программу-примитивный шифратор-дешифратор. При запуске указывается файл с текстом. Если в файле встречаются символы a-z, то они кодируются по алгоритму (придуманному разработчиком) рандомно сгенерированной строкой из символов a-z. Если встречаются другие символы, то они остаются без изменения. После выполняется дешифрирование с помощью всё той же рандомной строки.
Проблема состоит в следующем: некорректно работает функция дешифрирования: вся строка дешифруется одним и тем же символом. Не могу понять в чём проблема. Очень надеюсь на Вашу помощь!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#! /usr/bin/env python """ test_crypto: tests python cryptography code. """ import sys import char_translator import crypto from commands import getoutput usage = "usage: test_crypto filename" if len(sys.argv) != 2: print usage sys.exit(1) input_filename = sys.argv[1] output_filename = input_filename + ".encoded" # Generate a translation string which is a random permutation of # the letters in the range [a-z]. dictionary = char_translator.random_permute_chars() # Create a character translator object. try: dictionary = char_translator.CharTranslator(dictionary) except char_translator.InvalidTranslationString, e: print >> sys.stderr, "Invalid translation string created." print >> sys.stderr, "Aborting." sys.exit(1) # Encode the file using this object. crypt = crypto.Coder(dictionary) crypt.encode_file(input_filename, output_filename) # Decode the file using the same translator. new_input_filename = input_filename + ".new" crypt.decode_file(output_filename, new_input_filename) # Test to see if the two files are the same. output = getoutput("diff -q %s %s" % (input_filename, new_input_filename)) if output: print output print "Test failed!" else: print "Test passed!"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
# -*- coding: utf-8 -*- ''' Created on Mar 24, 2017 @author: alexander Генерация случайного кода подстановки и перевод символов от a - z ''' import string import random class InvalidTranslationString(): def __init__(self,value): self.msg = value def __str__(self): return self.msg class CharTranslator(): symbol_index = [[],[]] def __init__(self, string_translation): try: self.dictionary = string_translation for symbol in string_translation: if symbol not in string.ascii_lowercase: raise InvalidTranslationString("Invalid translation") except InvalidTranslationString as err: print(err.msg) def translate_char(self, symbol): if ord(symbol) >= 97 and ord(symbol) 122: index = ord(symbol) - ord('a') symbol = self.dictionary[index] self.symbol_index[0].append(symbol) self.symbol_index[1].append(index) return symbol else: self.symbol_index[0].append(symbol) self.symbol_index[1].append(0) return symbol def untranslate_char(self): len_string = ''.join(self.symbol_index[0]) for i in range(0, len(len_string), 1): symbol = self.symbol_index[0][i] index = self.symbol_index[1][i] if ord(symbol) >= 97 and ord(symbol) 122: code_symbols = index + ord('a') symbol = chr(code_symbols) return symbol else: return symbol def random_permute_chars(): dictionary = list(string.lowercase) random.shuffle(dictionary) return ''.join(dictionary)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
# -*- coding: utf-8 -*- ''' Created on Mar 24, 2017 @author: alexander Фактический перевод и перенос файлов ''' import char_translator class Coder(): def __init__(self, char_translator): self.charTranslator = char_translator def encode_file(self, inputFileName, OutputFileName): with open(inputFileName, 'r') as file: lines_output = [] for line in file: line_output = '' for symbols in line: line_output += self.charTranslator.translate_char(symbols) lines_output.append(line_output) file.close() with open(OutputFileName, 'w') as file: file.writelines(lines_output) file.close() def decode_file(self, inputFileName, OutputFileName): with open(inputFileName, 'r') as file: lines_output = [] for line in file: line_output = '' for symbols in line: line_output += self.charTranslator.untranslate_char() lines_output.append(line_output) file.close() with open(OutputFileName, 'w') as file: file.writelines(lines_output) file.close()
Добавлено через 1 час 29 минут
Проблема мною решена!
Можно закрывать тему
Были доработаны следующие файлы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
# -*- coding: utf-8 -*- ''' Created on Mar 24, 2017 @author: alexander Фактический перевод и перенос файлов ''' import char_translator class Coder(): def __init__(self, char_translator): self.charTranslator = char_translator def encode_file(self, inputFileName, OutputFileName): with open(inputFileName, 'r') as file: lines_output = [] for line in file: line_output = '' for symbols in line: line_output += self.charTranslator.translate_char(symbols) lines_output.append(line_output) file.close() with open(OutputFileName, 'w') as file: file.writelines(lines_output) file.close() def decode_file(self, inputFileName, OutputFileName): with open(inputFileName, 'r') as file: lines_output = [] i = 0 for line in file: line_output = '' for symbols in line: line_output += self.charTranslator.untranslate_char(symbols, i) i = i + 1 lines_output.append(line_output) file.close() with open(OutputFileName, 'w') as file: file.writelines(lines_output) file.close()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
# -*- coding: utf-8 -*- ''' Created on Mar 24, 2017 @author: alexander Генерация случайного кода подстановки и перевод символов от a - z ''' import string import random class InvalidTranslationString(): def __init__(self,value): self.msg = value def __str__(self): return self.msg class CharTranslator(): symbol_index = [[],[]] def __init__(self, string_translation): try: self.dictionary = string_translation for symbol in string_translation: if symbol not in string.ascii_lowercase: raise InvalidTranslationString("Invalid translation") except InvalidTranslationString as err: print(err.msg) def translate_char(self, symbol): if ord(symbol) >= 97 and ord(symbol) 122: index = ord(symbol) - ord('a') symbol = self.dictionary[index] self.symbol_index[0].append(symbol) self.symbol_index[1].append(index) return symbol else: self.symbol_index[0].append(symbol) self.symbol_index[1].append(0) return symbol def untranslate_char(self, symbol, index): number = self.symbol_index[1] print number number = number[index] print number if ord(symbol) >= 97 and ord(symbol) 122: code_symbols = number + ord('a') print code_symbols symbol = chr(code_symbols) print symbol return symbol else: return symbol def random_permute_chars(): dictionary = list(string.lowercase) random.shuffle(dictionary) return ''.join(dictionary)