-
Notifications
You must be signed in to change notification settings - Fork 0
added submission for sandips #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
""" | ||
Assignment 1: Cryptography | ||
Course: CS 92SI | ||
Name: SANDIP SRINIVAS | ||
Date: 7 OCTOBER 2015 | ||
|
||
This program implements multiple cryptography types: caesar, vigniere, and Railfence. | ||
The program gives the user the option of encrypting/decrypting into a file or string, | ||
and gives output accordingly. | ||
""" | ||
|
||
def encrypt_caesar(plaintext): | ||
mapping = {} | ||
for number in range(97, 122): | ||
if (number < 120): | ||
mapping[chr(number)] = chr(number + 3) | ||
else: | ||
mapping[chr(number)] = chr(97 + (number - 120)) | ||
ciphertext = "" | ||
for letter in plaintext: | ||
ciphertext += mapping[letter] | ||
return ciphertext | ||
|
||
def decrypt_caesar(ciphertext): | ||
mapping = {} | ||
for number in range(97, 122): | ||
if (number > 100): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
mapping[chr(number)] = chr(number - 3) | ||
else: | ||
mapping[chr(number)] = chr(122 - (99 - number)) | ||
plaintext = "" | ||
for letter in ciphertext: | ||
plaintext += mapping[letter] | ||
return plaintext | ||
|
||
|
||
def encrypt_vigenere(plaintext, keyword): | ||
mapping = {} | ||
for number in range(1, 26): | ||
mapping[chr(number + 96)] = number | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be really cool to build this map with the builtin lowercase letters provided by Python's
|
||
ciphertext = "" | ||
for index in range(0, len(plaintext)): | ||
ciphertext += chr(((mapping[plaintext[index]] + mapping[keyword[index]]) % 26) + 95) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah so this line is causing you issues when |
||
return ciphertext | ||
|
||
|
||
def decrypt_vigenere(ciphertext, keyword): | ||
print(ciphertext) | ||
print(keyword) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug prints |
||
mapping = {} | ||
for number in range(1, 26): | ||
mapping[chr(number + 96)] = number | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps a more pythonic way of building this map would be:
|
||
plaintext = "" | ||
for index in range(0, len(ciphertext)): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if (mapping[ciphertext[index]] >= mapping[keyword[index]]): | ||
plaintext += chr(mapping[ciphertext[index]] - mapping[keyword[index]] + 97) | ||
else: | ||
plaintext += chr(27 - abs(mapping[ciphertext[index]] - mapping[keyword[index]]) + 96) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not super clear where the |
||
return plaintext | ||
|
||
|
||
def encrypt_railfence(plaintext, num_rails): | ||
ciphertext = "" | ||
indexAdjust = 2 | ||
for rail in range(1, num_rails + 1): | ||
index = rail - 1 | ||
if (rail == 1 or rail == num_rails): | ||
ciphertext += plaintext[rail-1:len(plaintext):2*(num_rails -1)] | ||
else: | ||
ciphertext += plaintext[rail - 1] | ||
while (index < len(plaintext) - 1): | ||
index += ((2*(num_rails -1))) | ||
if (num_rails != 3): index -= indexAdjust | ||
if ( index < len(plaintext) - 1): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some weird spacing here |
||
ciphertext += plaintext[index] | ||
index += ((2*(num_rails -1)) - indexAdjust + 2) | ||
if (index < len(plaintext) - 1): | ||
ciphertext += plaintext[index] | ||
indexAdjust += 2 | ||
return ciphertext | ||
|
||
def decrypt_railfence(ciphertext, num_rails): | ||
plaintext = ciphertext[0] | ||
index = 0 | ||
adjust1 = 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps a more descriptive variable name here? |
||
while (len(plaintext) < len(ciphertext)): | ||
index += (int)(len(ciphertext) / num_rails) - 1 + adjust1 | ||
if (index < len(ciphertext)): | ||
plaintext += ciphertext[index] | ||
index += (int)(len(ciphertext) / (num_rails - 1)) - adjust1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is all a fair bit repeated - would appreciate factoring this logic out |
||
if (index < len(ciphertext)): | ||
plaintext += ciphertext[index] | ||
index -= (int)(len(ciphertext) / (num_rails - 1)) - adjust1 - 1 | ||
if (index < len(ciphertext)): | ||
plaintext += ciphertext[index] | ||
index -= (int)(len(ciphertext) / num_rails) - 1 + adjust1 | ||
if (index < len(ciphertext)): | ||
plaintext += ciphertext[index] | ||
++adjust1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general, this segment of code is a little hard to understand - we'd appreciate some comments in the future to explain some of the more complicated code segments |
||
|
||
print(plaintext) | ||
|
||
|
||
def read_from_file(filename): | ||
with open(filename, 'r') as f: | ||
content = f.read() | ||
return str(content) | ||
|
||
|
||
def write_to_file(filename, content): | ||
with open(filename, 'w') as f: | ||
f.write(content) | ||
|
||
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("*Input*") | ||
fileOrString = input("(F)ile or (S)tring? ") | ||
fileOrString = fileOrString.lower() | ||
while (not fileOrString.isalpha() or len(fileOrString) != 1 or | ||
fileOrString not in ['f', 's']): | ||
fileOrString = input("Please enter either an F for File or an S for String: ") | ||
fileOrString = fileOrString.lower() | ||
if (fileOrString == 'f'): | ||
filename = input("Filename? ") | ||
name = read_from_file(filename) | ||
else: | ||
name = input("Enter the string to encrypt: ") | ||
|
||
print("*Transform*") | ||
encryptOrDecrypt = input("(E)ncrypt or (D)ecrypt? ") | ||
encryptOrDecrypt = encryptOrDecrypt.lower() | ||
while (not encryptOrDecrypt.isalpha() or len(encryptOrDecrypt) != 1 or | ||
encryptOrDecrypt not in ['e', 'd']): | ||
encryptOrDecrypt = input("Please enter either an E for Encrypt or an D for Decrypt: ") | ||
encryptOrDecrypt = encryptOrDecrypt.lower() | ||
|
||
cipherType = input("(C)aesar, (V)igenere, or (R)ailfence? ") | ||
cipherType = cipherType.lower() | ||
while (not cipherType.isalpha() or len(cipherType) != 1 or | ||
cipherType not in ['c', 'v', 'r']): | ||
cipherType = input("Please enter either a C for Caesar, V for Vigniere, or R for Railfence: ") | ||
cipherType = cipherType.lower() | ||
|
||
if (cipherType == 'c'): | ||
if (encryptOrDecrypt == 'e'): | ||
print("Encrypting", name, "using Caesar cipher") | ||
output = encrypt_caesar(name.lower()) | ||
if (encryptOrDecrypt == 'd'): | ||
print("Decrypting", name, "using Caesar cipher") | ||
output = decrypt_caesar(name.lower()) | ||
|
||
if (cipherType == 'v'): | ||
passkey = input("Passkey? ") | ||
while (not passkey.isalpha()): | ||
passkey = input("Please enter a passkey of only English letters: ") | ||
if len(passkey) < len(name): | ||
difference = len(name) - len(passkey) | ||
for index in range(0, difference): | ||
passkey += passkey[index%len(name)] | ||
if len(passkey) > len(name): | ||
passkey = passkey[:len(name)-1] | ||
if (encryptOrDecrypt == 'e'): | ||
print("Encrypting", name, "using Vigniere cypher with key", passkey) | ||
output = encrypt_vigenere(name.lower(), passkey.lower()) | ||
if (encryptOrDecrypt == 'd'): | ||
print("Decrypting", name, "using Vigniere cypher with key", passkey) | ||
output = decrypt_vigenere(name.lower(), passkey.lower()) | ||
|
||
if (cipherType == 'r'): | ||
rails = input("Enter number of rails: ") | ||
while (not rails.isnumeric): | ||
rails = input("Please enter a positive integer number of rails: ") | ||
if (encryptOrDecrypt == 'e'): | ||
print("Encrypting", name, "using Railfence cipher with", rails, "rails") | ||
output = encrypt_railfence(name, int(rails)) | ||
if (encryptOrDecrypt == 'd'): | ||
print("Decrypting", name, "using Railfence cipher with", rails, "rails") | ||
output = decrypt_railfence(name, int(rails)) | ||
|
||
print("*Output*") | ||
fileOrString = input("(F)ile or (S)tring? ") | ||
fileOrString = fileOrString.lower() | ||
while (not fileOrString.isalpha() or len(fileOrString) != 1 or | ||
fileOrString not in ['f', 's']): | ||
fileOrString = input("Please enter either an F for File or an S for String: ") | ||
fileOrString = fileOrString.lower() | ||
if (fileOrString == 'f'): name = input("Filename? ") | ||
else: print(output) # Print or write the transformed output | ||
|
||
|
||
# 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() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Name: Sandip Srinivas | ||
1) How long did this assignment take you to complete? | ||
Roughly 5 hours | ||
|
||
|
||
2) What has been the best part of the class so far? | ||
Doing practice problems in class (anagrams, cyclone phrases, etc) | ||
|
||
|
||
|
||
|
||
3) What can we do to make this class more enjoyable for you? | ||
Teach more cool python specific things | ||
|
||
|
||
|
||
|
||
4) What types of assignments would excite you in this class? | ||
Games (i.e. brick breaker, boggle, but not as time consuming as boggle) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it - thanks for the suggestions |
||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've got a fair bit of magic constants here.