From 8fb5a781f7bef596aeffe2e205c59dd8bf264296 Mon Sep 17 00:00:00 2001 From: Sherman Leung Date: Wed, 28 Oct 2015 23:33:24 -0700 Subject: [PATCH 1/3] added submission for wizeng --- sunetids.txt | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sunetids.txt b/sunetids.txt index 97203b7..4d45e1b 100644 --- a/sunetids.txt +++ b/sunetids.txt @@ -1,19 +1 @@ -da6462 -jlwatson -bpham -gusliu -annaxw -mcm2018 -dsslater wizeng -keyur -lglucin -quint -hcarroll -alandeng -jamesc4 -sandips -gangus -csmith95 -desmondw -mateog \ No newline at end of file From c2dae478804b7e39c71c1107618d019483bbf323 Mon Sep 17 00:00:00 2001 From: Sherman Leung Date: Wed, 28 Oct 2015 23:34:31 -0700 Subject: [PATCH 2/3] added submission for wizeng --- wizeng-assign1/caesar-cipher.txt | 1 + wizeng-assign1/caesar-plain.txt | 1 + wizeng-assign1/crypto.py | 302 ++++++++++++++++++++++++++++ wizeng-assign1/feedback.txt | 23 +++ wizeng-assign1/railfence-cipher.txt | 1 + wizeng-assign1/railfence-plain.txt | 1 + wizeng-assign1/secret_message.txt | 1 + wizeng-assign1/vigenere-cipher.txt | 1 + wizeng-assign1/vigenere-plain.txt | 1 + 9 files changed, 332 insertions(+) create mode 100644 wizeng-assign1/caesar-cipher.txt create mode 100644 wizeng-assign1/caesar-plain.txt create mode 100644 wizeng-assign1/crypto.py create mode 100644 wizeng-assign1/feedback.txt create mode 100644 wizeng-assign1/railfence-cipher.txt create mode 100644 wizeng-assign1/railfence-plain.txt create mode 100644 wizeng-assign1/secret_message.txt create mode 100644 wizeng-assign1/vigenere-cipher.txt create mode 100644 wizeng-assign1/vigenere-plain.txt diff --git a/wizeng-assign1/caesar-cipher.txt b/wizeng-assign1/caesar-cipher.txt new file mode 100644 index 0000000..77ba61d --- /dev/null +++ b/wizeng-assign1/caesar-cipher.txt @@ -0,0 +1 @@ +SBWKRQ \ No newline at end of file diff --git a/wizeng-assign1/caesar-plain.txt b/wizeng-assign1/caesar-plain.txt new file mode 100644 index 0000000..38a33ed --- /dev/null +++ b/wizeng-assign1/caesar-plain.txt @@ -0,0 +1 @@ +PYTHON \ No newline at end of file diff --git a/wizeng-assign1/crypto.py b/wizeng-assign1/crypto.py new file mode 100644 index 0000000..6ab0e55 --- /dev/null +++ b/wizeng-assign1/crypto.py @@ -0,0 +1,302 @@ +""" +Assignment 1: Cryptography +Course: CS 92SI +Name: William Zeng +Date: 10/9/2015 + +Provides several functions to encrypt and decrypt text using several encryption algorithms. +""" + +def encrypt_caesar(plaintext): + """ + Encrypts plaintext using a Caesar cipher. + Add more implementation details here. + """ + + ciphertext = ""; + for letter in plaintext: + letter = chr(ord(letter) + 3); + if (not letter.isalpha()): + letter = chr(ord(letter) - 26); + ciphertext += letter; + return ciphertext + +def decrypt_caesar(ciphertext): + """ + Decrypts a ciphertext using a Caesar cipher. + Add more implementation details here. + """ + + plaintext = ""; + for letter in ciphertext: + letter = chr(ord(letter) - 3); + if (not letter.isalpha()): + letter = chr(ord(letter) + 26); + plaintext += letter; + return plaintext + +def encrypt_vigenere(plaintext, keyword): + """ + Encrypts plaintext using a Vigenere cipher with a keyword. + Add more implementation details here. + """ + + ciphertext = "" + for i in range(0, len(plaintext)): + #The following simplifies some of the addition for determining the enciphering + #In the middle of the letter 'b' with keyword letter 'L', it's ('b' - 'a' + 'L' - 'A') + 'a' = 'b' + 'L' - 'A' + letter = chr(ord(plaintext[i]) + ord(keyword[i % len(keyword)]) - ord('a' if keyword[i % len(keyword)].islower() else 'A')) + #In short, this tests whether adding the keyword to the letter makes it need to loop around + if ((not letter.isalpha()) or (letter.islower() and plaintext[i].isupper()) or (letter.isupper() and plaintext[i].islower())): + letter = chr(ord(letter) - 26); + ciphertext += letter; + return ciphertext + +def decrypt_vigenere(ciphertext, keyword): + """ + Decrypts ciphertext using a Vigenere cipher with a keyword. + Add more implementation details here. + """ + + plaintext = "" + for i in range(0, len(ciphertext)): + letter = chr(ord(ciphertext[i]) - ord(keyword[i % len(keyword)]) + ord('a' if keyword[i % len(keyword)].islower() else 'A')) + if ((not letter.isalpha()) or (letter.islower() and ciphertext[i].isupper()) or (letter.isupper() and ciphertext[i].islower())): + letter = chr(ord(letter) + 26); + plaintext += letter; + return plaintext + +def encrypt_railfence(plaintext, num_rails): + """ + Encrypts plaintext using a railfence cipher. + Add more implementation details here. + """ + + if num_rails == 1: + return plaintext + ciphertext = '' + rails = [] + for i in range(num_rails): + rails.append([]) + counter = 0 + increase = True + for letter in plaintext: + rails[counter] += letter + if increase: + counter += 1 + if counter == num_rails: + counter -= 2 + increase = not increase + else: + counter -= 1 + if counter == -1: + counter += 2 + increase = not increase + for rail in rails: + ciphertext += ''.join(rail) + return ciphertext + + +def decrypt_railfence(ciphertext, num_rails): + """ + Encrypts plaintext using a railfence cipher. + Add more implementation details here. + """ + + if num_rails == 1: + return ciphertext + plaintext = '' + num_on_rails = [] + for i in range(num_rails): + num_on_rails.append(0) + + counter = 0 + increase = True + for letter in ciphertext: + num_on_rails[counter] += 1 + if increase: + counter += 1 + if counter == num_rails: + counter -= 2 + increase = not increase + else: + counter -= 1 + if counter == -1: + counter += 2 + increase = not increase + + rails = [] + startCount = 0 + endCount = 0 + for i in range(num_rails): + endCount += num_on_rails[i] + rails.append(list(ciphertext[startCount:endCount:])) + startCount += num_on_rails[i] + + counter = 0 + increase = True + for letter in ciphertext: + plaintext += rails[counter].pop(0) + if increase: + counter += 1 + if counter == num_rails: + counter -= 2 + increase = not increase + else: + counter -= 1 + if counter == -1: + counter += 2 + increase = not increase + + return plaintext + +def read_from_file(filename): + """ + Reads and returns content from a file. + Add more implementation details here. + """ + + with open(filename, 'r') as iffy: + content = iffy.readlines() + return ' '.join(content) #concatenates all of the lines in the file together as a single string + +def write_to_file(filename, content): + """ + Writes content to a file. + Add more implementation details here. + """ + with open(filename, 'w') as offy: + offy.write(content) + +def clean_input(str): + newstr = '' + for char in str: + if (char.isalpha()): + newstr += char + return newstr + +def run_suite(): + """ + Runs a single iteration of the cryptography suite. + + Asks the user for input text from a string or file, whether to encrypt + or decrypt, what tool to use, and where to show the output. + """ + print('Welcome to the Cryptography Suite!') + print("*Input*") + file_or_string = input('(F)ile or (S)tring? ').lower() + while not (file_or_string == 'f' or file_or_string == 's'): + file_or_string = input('(F)ile or (S)tring? ').lower() + + input_text = '' + filename = '' + if file_or_string == 'f': + filename = input('Filename? ') + input_text = read_from_file(filename) + else: + input_text = input('Enter the string to (en/de)crypt: ') + + input_text = clean_input(input_text) + + print("*Transform*") + encrypt_or_decrypt = input('(E)ncrypt or (D)ecrypt? ').lower() + while not (encrypt_or_decrypt == 'e' or encrypt_or_decrypt == 'd'): + encrypt_or_decrypt = input('(E)ncrypt or (D)ecrypt? ').lower() + + crypt_type = input('(C)aesar, (V)igenere, or (R)ailfence? ').lower() + while not (crypt_type == 'c' or crypt_type == 'v' or crypt_type == 'r'): + crypt_type = input('(C)aesar, (V)igenere, or (R)ailfence? ').lower() + + inputStr = '' + if file_or_string == 'f': + inputStr = 'contents of ' + filename + else: + inputStr = input_text + + encr_or_decr = '' + if encrypt_or_decrypt == 'e': + encr_or_decr = 'Encrypting' + else: + encr_or_decr = 'Decrypting' + + cipher = '' + passkey = '' + rail_num = '' + if crypt_type == 'c': + cipher = 'Caesar cipher' + elif crypt_type == 'v': + passkey = input("Passkey? ") + cipher = 'Vigenere cipher with key ' + passkey + else: + rail_num = int(input("Number of rails? ")) + cipher = 'railfence cipher' + + print(encr_or_decr, inputStr, 'using', cipher) + print('...') + + print("*Output*") + + result_text = '' + if crypt_type == 'c': + if encrypt_or_decrypt == 'e': + result_text = encrypt_caesar(input_text) + else: + result_text = decrypt_caesar(input_text) + elif crypt_type == 'v': + if encrypt_or_decrypt == 'e': + result_text = encrypt_vigenere(input_text, passkey) + else: + result_text = decrypt_vigenere(input_text, passkey) + else: + if encrypt_or_decrypt == 'e': + result_text = encrypt_railfence(input_text, rail_num) + else: + result_text = decrypt_railfence(input_text, rail_num) + + + file_or_string = input('(F)ile or (S)tring? ').lower() + while not (file_or_string == 'f' or file_or_string == 's'): + file_or_string = input('(F)ile or (S)tring? ').lower() + + if file_or_string == 'f': + filename = input('Filename? ') + write_to_file(filename, result_text) + print('Writing ciphertext to ', filename, '...') + else: + if encrypt_or_decrypt == 'e': + encr_or_decr = 'ciphertext' + else: + encr_or_decr = 'plaintext' + print('The', encr_or_decr, 'is: ', result_text, '') + + + + + +# Do not modify code beneath this point. +def should_continue(): + """ + Asks the user whether they would like to continue. + Responses that begin with a `Y` return True. (case-insensitively) + Responses that begin with a `N` return False. (case-insensitively) + All other responses (including '') cause a reprompt. + """ + choice = input("Again (Y/N)? ").upper() + while not choice or choice[0] not in ['Y', 'N']: + choice = input("Please enter either 'Y' or 'N'. Again (Y/N)? ").upper() + return choice[0] == 'Y' + + +def main(): + """Harness for the Cryptography Suite""" + print("Welcome to the Cryptography Suite!") + run_suite() + while should_continue(): + run_suite() + print("Goodbye!") + + +if __name__ == '__main__': + """This block is run if and only if the Python script is invoked from the + command line.""" + main() diff --git a/wizeng-assign1/feedback.txt b/wizeng-assign1/feedback.txt new file mode 100644 index 0000000..3ad1f4a --- /dev/null +++ b/wizeng-assign1/feedback.txt @@ -0,0 +1,23 @@ +Name: William Zeng +1) How long did this assignment take you to complete? +7 hours + + +2) What has been the best part of the class so far? +Learning about the things that are so much easier to do/use in Python than other languages + + + + +3) What can we do to make this class more enjoyable for you? +Nothing! + + + + +4) What types of assignments would excite you in this class? +Those that cement the concepts in class but focus on a cool topic (i.e. this assignment teaching crypto) + + + + diff --git a/wizeng-assign1/railfence-cipher.txt b/wizeng-assign1/railfence-cipher.txt new file mode 100644 index 0000000..c1ae5da --- /dev/null +++ b/wizeng-assign1/railfence-cipher.txt @@ -0,0 +1 @@ +WECRLTEERDSOEEFEAOCAIVDEN \ No newline at end of file diff --git a/wizeng-assign1/railfence-plain.txt b/wizeng-assign1/railfence-plain.txt new file mode 100644 index 0000000..fc27f60 --- /dev/null +++ b/wizeng-assign1/railfence-plain.txt @@ -0,0 +1 @@ +WE ARE DISCOVERED. FLEE AT ONCE \ No newline at end of file diff --git a/wizeng-assign1/secret_message.txt b/wizeng-assign1/secret_message.txt new file mode 100644 index 0000000..860b90c --- /dev/null +++ b/wizeng-assign1/secret_message.txt @@ -0,0 +1 @@ +KHOORZRUOG \ No newline at end of file diff --git a/wizeng-assign1/vigenere-cipher.txt b/wizeng-assign1/vigenere-cipher.txt new file mode 100644 index 0000000..b04ec8d --- /dev/null +++ b/wizeng-assign1/vigenere-cipher.txt @@ -0,0 +1 @@ +LXFOPVEFRNHR \ No newline at end of file diff --git a/wizeng-assign1/vigenere-plain.txt b/wizeng-assign1/vigenere-plain.txt new file mode 100644 index 0000000..877099d --- /dev/null +++ b/wizeng-assign1/vigenere-plain.txt @@ -0,0 +1 @@ +Attack At Dawn! \ No newline at end of file From 1a61d500c80143cea546167655dab6718200a2bd Mon Sep 17 00:00:00 2001 From: Sherman Leung Date: Thu, 29 Oct 2015 00:39:42 -0700 Subject: [PATCH 3/3] added submission for mateog --- "mateog-assign1/Icon\r" | 0 .../caesar-cipher.txt | 0 .../caesar-plain.txt | 0 mateog-assign1/crypto.py | 322 ++++++++++++++++++ mateog-assign1/feedback.txt | 24 ++ .../railfence-cipher.txt | 0 .../railfence-plain.txt | 0 .../secret_message.txt | 0 .../vigenere-cipher.txt | 0 .../vigenere-plain.txt | 0 wizeng-assign1/crypto.py | 302 ---------------- wizeng-assign1/feedback.txt | 23 -- 12 files changed, 346 insertions(+), 325 deletions(-) create mode 100644 "mateog-assign1/Icon\r" rename {wizeng-assign1 => mateog-assign1}/caesar-cipher.txt (100%) rename {wizeng-assign1 => mateog-assign1}/caesar-plain.txt (100%) create mode 100644 mateog-assign1/crypto.py create mode 100644 mateog-assign1/feedback.txt rename {wizeng-assign1 => mateog-assign1}/railfence-cipher.txt (100%) rename {wizeng-assign1 => mateog-assign1}/railfence-plain.txt (100%) rename {wizeng-assign1 => mateog-assign1}/secret_message.txt (100%) rename {wizeng-assign1 => mateog-assign1}/vigenere-cipher.txt (100%) rename {wizeng-assign1 => mateog-assign1}/vigenere-plain.txt (100%) delete mode 100644 wizeng-assign1/crypto.py delete mode 100644 wizeng-assign1/feedback.txt diff --git "a/mateog-assign1/Icon\r" "b/mateog-assign1/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/wizeng-assign1/caesar-cipher.txt b/mateog-assign1/caesar-cipher.txt similarity index 100% rename from wizeng-assign1/caesar-cipher.txt rename to mateog-assign1/caesar-cipher.txt diff --git a/wizeng-assign1/caesar-plain.txt b/mateog-assign1/caesar-plain.txt similarity index 100% rename from wizeng-assign1/caesar-plain.txt rename to mateog-assign1/caesar-plain.txt diff --git a/mateog-assign1/crypto.py b/mateog-assign1/crypto.py new file mode 100644 index 0000000..811e5a9 --- /dev/null +++ b/mateog-assign1/crypto.py @@ -0,0 +1,322 @@ +""" +Assignment 1: Cryptography +Course: CS 92SI +Name: Mateo Garcia +Date: 2015-10-11 + +Encrypts and decrypts Caesar, Vigenere, and Railfence ciphers. +""" + +import math + +alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +def encrypt_caesar(plaintext): + """ + Encrypts plaintext using a Caesar cipher. Maps alphabet to cipher + alphabet shifted by three characters to the left, such that A maps to D, etc. + Converts plaintext to list, and finds ciphertext version of each + character using map. + """ + encrypt_alphabet = alphabet[3:] + alphabet[:3] + print(encrypt_alphabet) + encrypt_map = {} + for i in range (0, 26): + encrypt_map[alphabet[i]] = encrypt_alphabet[i] + + plaintext = plaintext.upper() + ciphertext = list(plaintext) + for i in range(0, len(plaintext)): + ciphertext[i] = encrypt_map[ciphertext[i]] + + return "".join(ciphertext) + + +def decrypt_caesar(ciphertext): + """ + Decrypts a ciphertext using a Caesar cipher. Maps alphabet to plaintext + alphabet shifted by three characters to the right, such that A maps to X, etc. + Converts ciphertext to list, and finds plaintext version of each + character using map. + """ + encrypt_alphabet = alphabet[-3:] + alphabet[:-3] + print(encrypt_alphabet) + encrypt_map = {} + for i in range (0, 26): + encrypt_map[alphabet[i]] = encrypt_alphabet[i] + + ciphertext = ciphertext.upper() + plaintext = list(ciphertext) + for i in range(0, len(ciphertext)): + plaintext[i] = encrypt_map[plaintext[i]] + + return "".join(plaintext) + + +def encrypt_vigenere(plaintext, keyword): + """ + Encrypts plaintext using a Vigenere cipher with a keyword. Creates + ciphertext list of same length as plaintext, gets ASCII value of + each letter in plaintext and corresponding letter in keyword, subtracts + value of 'A', adds key character value to plaintext value, mods sum by + 26 to get a wrapping shift, and adds 'A' back to sum before getting ASCII + character back from ciphertext value. + """ + plaintext = plaintext.upper() + keyword = keyword.upper() + ciphertext = list(plaintext) + for i in range(0, len(plaintext)): + p = ord(plaintext[i]) - ord('A') + k = ord(keyword[i % len(keyword)]) - ord('A') + ciphertext[i] = chr(((p + k) % 26) + ord('A')) + + return "".join(ciphertext) + + +def decrypt_vigenere(ciphertext, keyword): + """ + Decrypts ciphertext using a Vigenere cipher with a keyword. Creates + plaintext list of same length as ciphertext, gets ASCII value of + each letter in ciphertext and corresponding letter in keyword, subtracts + value of 'A' from each, subtracts key character value from ciphertext value, + mods sum by 26 to get a wrapping shift, and adds 'A' back to sum before + getting ASCII character back from plaintext value. + """ + ciphertext = ciphertext.upper() + keyword = keyword.upper() + plaintext = list(ciphertext) + for i in range(0, len(ciphertext)): + p = ord(ciphertext[i]) - ord('A') + k = ord(keyword[i % len(keyword)]) - ord('A') + plaintext[i] = chr(((p - k) % 26) + ord('A')) + + return "".join(plaintext) + + +def encrypt_railfence(plaintext, num_rails): + """ + Encrypts plaintext using a railfence cipher. Sets plaintext to uppercase, + and loops through each character in plaintext to determine its rail. First + splits characters into fragments, which include the character at a peak/trough + (inclusive) through the character at the next peak/trough (exclusive). Next, + determines whether fragment is descending or ascending, and splits characters + from the start of the fragment to the end into their corresponding rail of + increasing index, or the opposite, respectively. + """ + plaintext = plaintext.upper() + frag_len = num_rails - 1 + rails = [""] * num_rails + for i in range(0, len(plaintext)): + frag_num = int(i / frag_len) + if frag_num % 2 == 0: + rails[i % frag_len] += plaintext[i] + else: + rails[-(1 + i % frag_len)] += plaintext[i] + + ciphertext = "" + for r in rails: + ciphertext += r + + return ciphertext + + +def decrypt_railfence(ciphertext, num_rails): + """ + Encrypts plaintext using a railfence cipher. + Add more implementation details here. + """ + ciphertext = ciphertext.upper() + frag_len = num_rails - 1 + rails = [""] * num_rails + num_full_frags = int(len(ciphertext) / frag_len) + len_last_frag = len(ciphertext) % frag_len + for i in range(0, num_rails): + + # TOP RAIL + if i == 0: + num_peaks = int(num_full_frags / 2) + if num_full_frags % 2 != 0 or len_last_frag > 0: # If extra letter from full/part fragment + num_peaks += 1 + rails[i] = ['-'] * num_peaks + + # BOTTOM RAIL + elif i == num_rails - 1: + num_troughs = int(num_full_frags / 2) + if num_full_frags % 2 != 0 and len_last_frag > 0: # If extra letter from full/part fragment + num_troughs += 1 + rails[i] = ['-'] * num_troughs + + # MIDDLE RAILS + else: + num_chars = num_full_frags + if num_full_frags % 2 == 0 and len_last_frag > i: # same as ^^ + num_chars += 1 + elif num_full_frags % 2 != 0 and num_rails - len_last_frag <= i: # same as ^^ + num_chars += 1 + rails[i] = ['-'] * num_chars + + # CONSTRUCT RAILS + spacing = frag_len * 2 + for i in range(0, num_rails): + if i == 0 or i == num_rails - 1: + rails[i] = ciphertext[::spacing] + else: + rails[i][::2] = ciphertext[::spacing] + odd_index_char_start = i + ((frag_len - i) * 2) + rails[i][1::2] = ciphertext[odd_index_char_start::spacing] + + # CONSTRUCT FRAGMENTS + num_frags = num_full_frags + if num_full_frags > 0: + num_frags += 1 + frags = [""] * num_frags + for i in range(0, num_frags): + startIndex = i * frag_len + frags[i] = ciphertext[startIndex:startIndex + frag_len] + + # CONVERT TO PLAINTEXT + plaintext = list(ciphertext) + for i in range(0, len(ciphertext)): + frag_num = int(i / frag_len) + if frag_num % 2 == 0: + plaintext[i] = rails[i % frag_len][0] + rails[i % frag_len] = rails[i % frag_len][1:] + else: + plaintext[i] = rails[-(1 + i % frag_len)][0] + rails[-(1 + i % frag_len)] = rails[-(1 + i % frag_len)][1:] + + return "".join(plaintext) + +def read_from_file(filename): + """ + Reads and returns content from a file. + Add more implementation details here. + """ + text = "" + with open(filename, 'r') as f: + text = f.read() + + return text + + +def write_to_file(filename, content): + """ + Writes content to a file. + Add more implementation details here. + """ + with open(filename, 'w') as f: + f.write(content) + + +def clean_up_text(text): + text = text.upper() + text = list(text) + i = 0 + while i < len(text): + if not text[i].isalpha(): + text.remove(text[i]) + else: + i += 1 + return "".join(text) + + +def run_suite(): + """ + Runs a single iteration of the cryptography suite. + + Asks the user for input text from a string or file, whether to encrypt + or decrypt, what tool to use, and where to show the output. + + Assumes filenames are valid. + """ + + # INPUT + print("*Input*") + choice = input("(F)ile or (S)tring? ").upper() + while not choice or choice[0] not in ['F', 'S']: + choice = input("Please enter either 'F' or 'S'. (F)ile or (S)tring? ").upper() + + text = "" + if choice == 'F': + filename = input("Filename? ") + text = read_from_file(filename) + text = clean_up_text(text) + else: + text = input("Enter the string to encrypt: ") + text = clean_up_text(text) + + # TRANSFORM + print("*Transform*") + choice = input("(E)ncrypt or (D)ecrypt? ").upper() + while not choice or choice[0] not in ['E', 'D']: + choice = input("Please enter either 'E' or 'D'. (E)ncrypt or (D)ecrypt? ").upper() + encrypt = choice == 'E' + + choice = input("(C)aesar, (V)igenere, or (R)ailfence? ").upper() + while not choice or choice[0] not in ['C', 'V', 'R']: + choice = input("Please enter either 'C', 'V', or 'R'. (C)aesar, (V)igenere, or (R)ailfence? ").upper() + + # CIPHER TYPE + result = "" + if choice == 'C': + if encrypt: + result = encrypt_caesar(text) + else: + result = decrypt_caesar(text) + elif choice == 'V': + keyword = input("Passkey? ") + if encrypt: + result = encrypt_vigenere(text, keyword) + else: + result = decrypt_vigenere(text, keyword) + else: + num_rails = input("Number of rails? ") + while not num_rails.isdigit(): + num_rails = input("Please enter a valid number. Number of rails? ") + num_rails = int(num_rails) + if encrypt: + result = encrypt_railfence(text, num_rails) + else: + result = decrypt_railfence(text, num_rails) + + # OUTPUT + print("*Output*") + choice = input("(F)ile or (S)tring? ").upper() + while not choice or choice[0] not in ['F', 'S']: + choice = input("Please enter either 'F' or 'S'. (F)ile or (S)tring? ").upper() + + if choice == 'F': + filename = input("Filename? ") + print("Writing ciphertext to", filename, "...") + write_to_file(filename, result) + else: + print("The plaintext is: ", result) + + +# Do not modify code beneath this point. +def should_continue(): + """ + Asks the user whether they would like to continue. + Responses that begin with a `Y` return True. (case-insensitively) + Responses that begin with a `N` return False. (case-insensitively) + All other responses (including '') cause a reprompt. + """ + choice = input("Again (Y/N)? ").upper() + while not choice or choice[0] not in ['Y', 'N']: + choice = input("Please enter either 'Y' or 'N'. Again (Y/N)? ").upper() + return choice[0] == 'Y' + + +def main(): + """Harness for the Cryptography Suite""" + print("Welcome to the Cryptography Suite!") + run_suite() + while should_continue(): + run_suite() + print("Goodbye!") + + +if __name__ == '__main__': + """This block is run if and only if the Python script is invoked from the + command line.""" + main() diff --git a/mateog-assign1/feedback.txt b/mateog-assign1/feedback.txt new file mode 100644 index 0000000..b316078 --- /dev/null +++ b/mateog-assign1/feedback.txt @@ -0,0 +1,24 @@ +Name: +1) How long did this assignment take you to complete? +6 hours. + + +2) What has been the best part of the class so far? +Getting to really develop Python skills on the homework. + + + + +3) What can we do to make this class more enjoyable for you? +The railfence decryption was super hard! Some more guidance would have been appreciated. +I guess I could have gone to office hours. + + + + +4) What types of assignments would excite you in this class? +Some scripts that leverage system tools, or some sort of look at what back-end programming is like. + + + + diff --git a/wizeng-assign1/railfence-cipher.txt b/mateog-assign1/railfence-cipher.txt similarity index 100% rename from wizeng-assign1/railfence-cipher.txt rename to mateog-assign1/railfence-cipher.txt diff --git a/wizeng-assign1/railfence-plain.txt b/mateog-assign1/railfence-plain.txt similarity index 100% rename from wizeng-assign1/railfence-plain.txt rename to mateog-assign1/railfence-plain.txt diff --git a/wizeng-assign1/secret_message.txt b/mateog-assign1/secret_message.txt similarity index 100% rename from wizeng-assign1/secret_message.txt rename to mateog-assign1/secret_message.txt diff --git a/wizeng-assign1/vigenere-cipher.txt b/mateog-assign1/vigenere-cipher.txt similarity index 100% rename from wizeng-assign1/vigenere-cipher.txt rename to mateog-assign1/vigenere-cipher.txt diff --git a/wizeng-assign1/vigenere-plain.txt b/mateog-assign1/vigenere-plain.txt similarity index 100% rename from wizeng-assign1/vigenere-plain.txt rename to mateog-assign1/vigenere-plain.txt diff --git a/wizeng-assign1/crypto.py b/wizeng-assign1/crypto.py deleted file mode 100644 index 6ab0e55..0000000 --- a/wizeng-assign1/crypto.py +++ /dev/null @@ -1,302 +0,0 @@ -""" -Assignment 1: Cryptography -Course: CS 92SI -Name: William Zeng -Date: 10/9/2015 - -Provides several functions to encrypt and decrypt text using several encryption algorithms. -""" - -def encrypt_caesar(plaintext): - """ - Encrypts plaintext using a Caesar cipher. - Add more implementation details here. - """ - - ciphertext = ""; - for letter in plaintext: - letter = chr(ord(letter) + 3); - if (not letter.isalpha()): - letter = chr(ord(letter) - 26); - ciphertext += letter; - return ciphertext - -def decrypt_caesar(ciphertext): - """ - Decrypts a ciphertext using a Caesar cipher. - Add more implementation details here. - """ - - plaintext = ""; - for letter in ciphertext: - letter = chr(ord(letter) - 3); - if (not letter.isalpha()): - letter = chr(ord(letter) + 26); - plaintext += letter; - return plaintext - -def encrypt_vigenere(plaintext, keyword): - """ - Encrypts plaintext using a Vigenere cipher with a keyword. - Add more implementation details here. - """ - - ciphertext = "" - for i in range(0, len(plaintext)): - #The following simplifies some of the addition for determining the enciphering - #In the middle of the letter 'b' with keyword letter 'L', it's ('b' - 'a' + 'L' - 'A') + 'a' = 'b' + 'L' - 'A' - letter = chr(ord(plaintext[i]) + ord(keyword[i % len(keyword)]) - ord('a' if keyword[i % len(keyword)].islower() else 'A')) - #In short, this tests whether adding the keyword to the letter makes it need to loop around - if ((not letter.isalpha()) or (letter.islower() and plaintext[i].isupper()) or (letter.isupper() and plaintext[i].islower())): - letter = chr(ord(letter) - 26); - ciphertext += letter; - return ciphertext - -def decrypt_vigenere(ciphertext, keyword): - """ - Decrypts ciphertext using a Vigenere cipher with a keyword. - Add more implementation details here. - """ - - plaintext = "" - for i in range(0, len(ciphertext)): - letter = chr(ord(ciphertext[i]) - ord(keyword[i % len(keyword)]) + ord('a' if keyword[i % len(keyword)].islower() else 'A')) - if ((not letter.isalpha()) or (letter.islower() and ciphertext[i].isupper()) or (letter.isupper() and ciphertext[i].islower())): - letter = chr(ord(letter) + 26); - plaintext += letter; - return plaintext - -def encrypt_railfence(plaintext, num_rails): - """ - Encrypts plaintext using a railfence cipher. - Add more implementation details here. - """ - - if num_rails == 1: - return plaintext - ciphertext = '' - rails = [] - for i in range(num_rails): - rails.append([]) - counter = 0 - increase = True - for letter in plaintext: - rails[counter] += letter - if increase: - counter += 1 - if counter == num_rails: - counter -= 2 - increase = not increase - else: - counter -= 1 - if counter == -1: - counter += 2 - increase = not increase - for rail in rails: - ciphertext += ''.join(rail) - return ciphertext - - -def decrypt_railfence(ciphertext, num_rails): - """ - Encrypts plaintext using a railfence cipher. - Add more implementation details here. - """ - - if num_rails == 1: - return ciphertext - plaintext = '' - num_on_rails = [] - for i in range(num_rails): - num_on_rails.append(0) - - counter = 0 - increase = True - for letter in ciphertext: - num_on_rails[counter] += 1 - if increase: - counter += 1 - if counter == num_rails: - counter -= 2 - increase = not increase - else: - counter -= 1 - if counter == -1: - counter += 2 - increase = not increase - - rails = [] - startCount = 0 - endCount = 0 - for i in range(num_rails): - endCount += num_on_rails[i] - rails.append(list(ciphertext[startCount:endCount:])) - startCount += num_on_rails[i] - - counter = 0 - increase = True - for letter in ciphertext: - plaintext += rails[counter].pop(0) - if increase: - counter += 1 - if counter == num_rails: - counter -= 2 - increase = not increase - else: - counter -= 1 - if counter == -1: - counter += 2 - increase = not increase - - return plaintext - -def read_from_file(filename): - """ - Reads and returns content from a file. - Add more implementation details here. - """ - - with open(filename, 'r') as iffy: - content = iffy.readlines() - return ' '.join(content) #concatenates all of the lines in the file together as a single string - -def write_to_file(filename, content): - """ - Writes content to a file. - Add more implementation details here. - """ - with open(filename, 'w') as offy: - offy.write(content) - -def clean_input(str): - newstr = '' - for char in str: - if (char.isalpha()): - newstr += char - return newstr - -def run_suite(): - """ - Runs a single iteration of the cryptography suite. - - Asks the user for input text from a string or file, whether to encrypt - or decrypt, what tool to use, and where to show the output. - """ - print('Welcome to the Cryptography Suite!') - print("*Input*") - file_or_string = input('(F)ile or (S)tring? ').lower() - while not (file_or_string == 'f' or file_or_string == 's'): - file_or_string = input('(F)ile or (S)tring? ').lower() - - input_text = '' - filename = '' - if file_or_string == 'f': - filename = input('Filename? ') - input_text = read_from_file(filename) - else: - input_text = input('Enter the string to (en/de)crypt: ') - - input_text = clean_input(input_text) - - print("*Transform*") - encrypt_or_decrypt = input('(E)ncrypt or (D)ecrypt? ').lower() - while not (encrypt_or_decrypt == 'e' or encrypt_or_decrypt == 'd'): - encrypt_or_decrypt = input('(E)ncrypt or (D)ecrypt? ').lower() - - crypt_type = input('(C)aesar, (V)igenere, or (R)ailfence? ').lower() - while not (crypt_type == 'c' or crypt_type == 'v' or crypt_type == 'r'): - crypt_type = input('(C)aesar, (V)igenere, or (R)ailfence? ').lower() - - inputStr = '' - if file_or_string == 'f': - inputStr = 'contents of ' + filename - else: - inputStr = input_text - - encr_or_decr = '' - if encrypt_or_decrypt == 'e': - encr_or_decr = 'Encrypting' - else: - encr_or_decr = 'Decrypting' - - cipher = '' - passkey = '' - rail_num = '' - if crypt_type == 'c': - cipher = 'Caesar cipher' - elif crypt_type == 'v': - passkey = input("Passkey? ") - cipher = 'Vigenere cipher with key ' + passkey - else: - rail_num = int(input("Number of rails? ")) - cipher = 'railfence cipher' - - print(encr_or_decr, inputStr, 'using', cipher) - print('...') - - print("*Output*") - - result_text = '' - if crypt_type == 'c': - if encrypt_or_decrypt == 'e': - result_text = encrypt_caesar(input_text) - else: - result_text = decrypt_caesar(input_text) - elif crypt_type == 'v': - if encrypt_or_decrypt == 'e': - result_text = encrypt_vigenere(input_text, passkey) - else: - result_text = decrypt_vigenere(input_text, passkey) - else: - if encrypt_or_decrypt == 'e': - result_text = encrypt_railfence(input_text, rail_num) - else: - result_text = decrypt_railfence(input_text, rail_num) - - - file_or_string = input('(F)ile or (S)tring? ').lower() - while not (file_or_string == 'f' or file_or_string == 's'): - file_or_string = input('(F)ile or (S)tring? ').lower() - - if file_or_string == 'f': - filename = input('Filename? ') - write_to_file(filename, result_text) - print('Writing ciphertext to ', filename, '...') - else: - if encrypt_or_decrypt == 'e': - encr_or_decr = 'ciphertext' - else: - encr_or_decr = 'plaintext' - print('The', encr_or_decr, 'is: ', result_text, '') - - - - - -# Do not modify code beneath this point. -def should_continue(): - """ - Asks the user whether they would like to continue. - Responses that begin with a `Y` return True. (case-insensitively) - Responses that begin with a `N` return False. (case-insensitively) - All other responses (including '') cause a reprompt. - """ - choice = input("Again (Y/N)? ").upper() - while not choice or choice[0] not in ['Y', 'N']: - choice = input("Please enter either 'Y' or 'N'. Again (Y/N)? ").upper() - return choice[0] == 'Y' - - -def main(): - """Harness for the Cryptography Suite""" - print("Welcome to the Cryptography Suite!") - run_suite() - while should_continue(): - run_suite() - print("Goodbye!") - - -if __name__ == '__main__': - """This block is run if and only if the Python script is invoked from the - command line.""" - main() diff --git a/wizeng-assign1/feedback.txt b/wizeng-assign1/feedback.txt deleted file mode 100644 index 3ad1f4a..0000000 --- a/wizeng-assign1/feedback.txt +++ /dev/null @@ -1,23 +0,0 @@ -Name: William Zeng -1) How long did this assignment take you to complete? -7 hours - - -2) What has been the best part of the class so far? -Learning about the things that are so much easier to do/use in Python than other languages - - - - -3) What can we do to make this class more enjoyable for you? -Nothing! - - - - -4) What types of assignments would excite you in this class? -Those that cement the concepts in class but focus on a cool topic (i.e. this assignment teaching crypto) - - - -