Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- # Crypto Corgi Company
- Build some simple functions for encrypting, decrypting, and hashing text
- for cryptography purposes.
- Date: Fall 2019
- Course: CISC108
- School: University of Delaware
- # When You Are Done
- When you pass all tests, remember to clean and document your code.
- But we will be reviewing your documentation and code quality!
- Yes, you have to unit test all your functions.
- """
- from cisc108 import assert_equal
- def convert_text(message:str) -> [int]:
- '''
- Consumes a 'message' and produces a list of integers where each character
- gets converted to an int using the ASCII table.
- Args:
- message (str): The string of text, it can be any message as long as
- it is a valid string.
- Returns:
- list[int]: the list of ints after the each value in the string was
- converted to an int.
- '''
- new_list = []
- for a_character in message:
- new_list.append(ord(a_character))
- return new_list
- assert_equal(convert_text("A!"),[65,33])
- assert_equal(convert_text("CGM"),[67,71,77])
- assert_equal(convert_text("{!"),[123,33])
- def shift_list(list_of_nums:[int],shift: int) -> [int]:
- '''
- Consumes a list of integers and a shift value. The list is shifted forward by
- 'shift' amount. For example, shifting the string "Apple" by 1 would create
- "eAppl".
- Args:
- list_of_nums (list[int]): The list of integers
- shift (int): The amount the list is shifted forward.
- Returns:
- list[int]: the list of ints after the each value in the list was shifted by
- 'shift' amount.
- '''
- for x in range(shift):
- list_of_nums = [list_of_nums[-1]] + list_of_nums[:-1]
- return list_of_nums
- assert_equal(shift_list([1,2,3,4,5], 1),[5,1,2,3,4])
- assert_equal(shift_list([1,2,3,4,5], 3),[3,4,5,1,2])
- assert_equal(shift_list([1,2,3,4,5], 4),[2,3,4,5,1])
- def rotate_list(list_of_nums:[int], rotate:int) -> [int]:
- '''
- Consumes a list of integers and a rotate value. The list is rotated by 'rotate'
- amount using a rotation formula.
- Args:
- list_of_nums (list[int]): The list of integers.
- rotate (int): The amount the list is being rotated by.
- Returns:
- list[int]: the list of ints after the each value in the list was rotated by
- 'rotate' amount.
- '''
- new_list = []
- for a_number in list_of_nums:
- new_list.append((a_number + rotate - 32) % 94 + 32)
- return new_list
- assert_equal(rotate_list([1,2,3,4,5],2),[97,98,99,100,101])
- assert_equal(rotate_list([110],50),[66])
- assert_equal(rotate_list([67],12),[79])
- assert_equal(rotate_list([0],10),[104])
- def insert_tilde(list_of_nums:[int]) -> [int]:
- '''
- Consumes a list of integers. After every integer value that is less than 48, the
- ASCII value of "~" which is 126 will be appended.
- Args:
- list_of_nums (list[int]): A list of integers.
- Returns:
- list[int]: A new list of integers with the value 126 inserted after every
- value in the list that is less than 48.
- '''
- new_list = []
- for a_number in list_of_nums:
- if a_number < 48:
- new_list.append(a_number)
- new_list.append(126)
- else:
- new_list.append(a_number)
- return new_list
- assert_equal(insert_tilde([125,48,23,123,4,5]),[125,48,23,126,123,4,126,5,126])
- assert_equal(insert_tilde([1,2,3,4,5]),[1,126,2,126,3,126,4,126,5,126])
- def convert_to_str(list_of_nums:[int]) -> str:
- '''
- Consumes a list of integers and produces a string where each
- value gets converted to a character using the ASCII table.
- Args:
- list_of_nums (list[int]): A list of integers
- Returns:
- str: The string produced after each value in the list was converted
- back to a character.
- '''
- new_str = ""
- for a_number in list_of_nums:
- new_str = new_str + chr(a_number)
- return new_str
- assert_equal(convert_to_str([49,50,51,52,53]),"12345")
- assert_equal(convert_to_str([123]),"{")
- def encrypt_text(message: str, shift: int, rotation: int) -> str:
- '''
- Consumes a string (plaintext message) and two integers (shift, and rotation),
- and produces a new string that is encrypted.
- Args:
- message (str): A plaintext message.
- shift (int): The amount that the list will be shifted.
- rotation (int): The amount that the list will be rotated.
- Returns:
- str: The new string that is encrypted.
- '''
- shifted_list = shift_list(convert_text(message),shift)
- encrypted_text = convert_to_str(insert_tilde(rotate_list(shifted_list,rotation)))
- return encrypted_text
- assert_equal(encrypt_text("abcdefg",3,2),"ghicdef")
- assert_equal(encrypt_text("Hello world!",3,10),'vn+~Rovvy*~#~y|')
- def remove_tilda(list_of_nums:[int]) -> [int]:
- '''
- Consumes a list of integers. For every value of 126 in the list, it
- will be removed.
- Args:
- list_of_nums (list[int]): A list of integers.
- Returns:
- list[int]: A new list of integers without any occurences of the value
- 126.
- '''
- new_list = []
- for a_num in list_of_nums:
- if a_num != 126:
- new_list.append(a_num)
- return new_list
- assert_equal(remove_tilda([1234,123,5,12,3,126,6,3,126]),[1234,123,5,12,3,6,3])
- assert_equal(remove_tilda([126,126,126,126,126,126,1,2,6]),[1,2,6])
- def rotate_negative(list_of_nums:[int],rotate:int) -> [int]:
- '''
- Consumes a list of integers and a rotate value. The list is rotated by (-'rotate')
- amount using a rotation formula.
- Args:
- list_of_nums (list[int]): The list of integers.
- rotate (int): The negative amount the list is being rotated by.
- Returns:
- list[int]: the list of ints after the each value in the list was rotated by
- (-'rotate') amount.
- '''
- new_list = []
- for a_number in list_of_nums:
- new_list.append((a_number + (-rotate) - 32) % 94 + 32)
- return new_list
- assert_equal(rotate_negative([1,2,3,4,5],2),[93, 94, 95, 96, 97])
- assert_equal(rotate_negative([123],10),[113])
- assert_equal(rotate_negative([0],10),[84])
- def shift_negative(list_of_nums:[int],shift: int) -> [int]:
- '''
- Consumes a list of integers and a shift value. The list is shifted forward by
- (-'shift') amount. For example, shifting the string "Apple" by -1 would create
- "ppleA".
- Args:
- list_of_nums (list[int]): The list of integers
- shift (int): The amount the list is shifted backwards.
- Returns:
- list[int]: The list of ints after the each value in the list was shifted
- backwards by 'shift' amount.
- '''
- for x in range(shift):
- list_of_nums = list_of_nums[1:] + [list_of_nums[0]]
- return list_of_nums
- assert_equal(shift_negative([1,2,3,4,5],2),[3,4,5,1,2])
- assert_equal(shift_negative([0,10,-1,-6],6),[-1, -6, 0, 10])
- def decrypt_text(encrypted_message: str, shift: int, rotation: int) -> str:
- '''
- Consumes a string (encrypted message) and two integers (shift, and rotation),
- and produces a new string that is decrypted.
- Args:
- encrypted_message (str): A message that has already been encrypted.
- shift (int): The amount the listed will be shifted backwards.
- rotate (int): The amount the list will be negatively rotated.
- Returns:
- str: The new string that has been decrypted.
- '''
- rotated_list = rotate_negative(remove_tilda(convert_text(encrypted_message)),rotation)
- decrypted_text = convert_to_str(shift_negative(rotated_list,shift))
- return decrypted_text
- assert_equal(decrypt_text('vn+~Rovvy*~#~y|',3,10),'Hello world!')
- assert_equal(decrypt_text('ghicdef',3,2),'abcdefg')
- assert_equal(decrypt_text('B',1,1),'A')
- def hash_convert(list_of_nums:[int], base: int) -> [int]:
- '''
- Consumes a list of numbers that will be changed using the following formula:
- new value = (index + base) ** (old value).
- Args:
- list_of_nums (list[int]): A list of integers.
- base (int): A value that will be used in the formula to tranform the list.
- Returns:
- list[int]: The new list after each value has been transformed.
- '''
- new_list = []
- index = 0
- for a_number in list_of_nums:
- new_list.append((index + base)**a_number)
- index = index + 1
- return new_list
- assert_equal(hash_convert([1,2,3,4,5],3),[3, 16, 125, 1296, 16807])
- assert_equal(hash_convert([0],100),[1])
- assert_equal(hash_convert([100],10),[10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000])
- def sum_list(list_of_nums:[int]) -> int:
- '''
- Consumes a list of integers and sums the list of integers.
- Args:
- list_of_nums (list[int]): A list of integers.
- Returns:
- int: The sum value of all the values in the list.
- '''
- sum = 0
- for a_number in list_of_nums:
- sum += a_number
- return sum
- assert_equal(sum_list([1,2,3,4,5]),15)
- assert_equal(sum_list([0]),0)
- assert_equal(sum_list([-1,-2,-3,-4,-5]),-15)
- def limit_hash_size(total_sum: int, hash_size: int) -> int:
- '''
- Consumes a total sum and a hash size and uses the modulo operator (%)
- to limit the total value to the hash size.
- Args:
- total_sum (int): A total value.
- hash_size (int): A value that the total value will be limited by.
- Returns:
- int: The value that the total value is limited by because of the hash size.
- '''
- return total_sum % hash_size
- assert_equal(limit_hash_size(15,4),3)
- assert_equal(limit_hash_size(0,100),0)
- assert_equal(limit_hash_size(100,5),0)
- def hash_text(text: str, base: int, hash_size: int) -> int:
- '''
- Consumes a string (any text) and two integers (base and hash_size), and produces an
- integer that attempts to uniquely represent the text.
- Args:
- text (str): Any valid string message.
- base (int): A value that will be used in a formula to tranform the list.
- hash_size (int): A value that the total value will be limited by.
- Returns:
- int: an integer that uniquely represents the original text.
- '''
- converted_list = hash_convert(convert_text(text),base)
- return int(limit_hash_size(sum_list(converted_list),hash_size))
- assert_equal(hash_text('abcdefg',3,1000000000),62589600)
- def main():
- """
- Main function that calls all the other functions and provides
- an crypto experience
- """
- action = input("What would you like to do? ")
- shift = 3
- rotate = 10
- base = 3
- hash_size = 1000000000
- if action == "encrypt":
- message = input("Enter a message. ")
- encrypted_message = encrypt_text(message,int(shift), int(rotate))
- hashed_text = hash_text(encrypted_message, base, hash_size)
- print("You're encrypted message is " + encrypted_message)
- print("You're hashed text is " + str(hashed_text))
- elif action == "decrypt":
- message = input("Enter your encrypted message. ")
- decrypted_message = decrypt_text(message, int(shift), int(rotate))
- expected_hash = input("Enter your expected hash. ")
- actual_hash = hash_text(decrypted_message, base, hash_size)
- if actual_hash == int(expected_hash):
- print(decrypted_message)
- else:
- print("Error Error Error")
- else:
- print("There is an error. Goodbye.")
- # ...
- # The following lines of code are used to call the main function.
- # Professional Python programmers always guard their main function call with
- # this IF statement, to make it easier for other users to call their code.
- # For now, just leave this code alone, but recognize that it is how you are
- # calling your main function.
- if __name__ == '__main__':
- main()
- """
- #Extra Credit Questions
- 1. Define the term "Security through Obscurity" and explain why it is not a good idea,
- in the context of Ada's Crypto Corgi Company.
- 2. Define and explain the difference between integrity, authentication, and confidentiality.
- Given these terms, what is the important difference between sending the hash values and the
- encrypted message?
- 3. Look up the term "Hash Collision". Find two strings that hash together using Ada's hashing
- algorithm for the base 31 and hash_size 10**9.
- 4. Decrypt the following text. Note that each line is using a different set of integers for the shift
- and rotation.
- """
Add Comment
Please, Sign In to add comment