Advertisement
Guest User

Untitled

a guest
Feb 26th, 2020
345
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.43 KB | None | 0 0
  1. """CSC108 Assignment 2 functions"""
  2.  
  3. from typing import List
  4.  
  5. # Used to determine whether to encrypt or decrypt
  6. ENCRYPT = 'e'
  7. DECRYPT = 'd'
  8.  
  9.  
  10. def clean_message(message: str) -> str:
  11. """Return a string with only uppercase letters from message with non-
  12. alphabetic characters removed.
  13.  
  14. >>> clean_message('Hello world!')
  15. 'HELLOWORLD'
  16. >>> clean_message("Python? It's my favourite language.")
  17. 'PYTHONITSMYFAVOURITELANGUAGE'
  18. >>> clean_message('88test')
  19. 'TEST'
  20. """
  21. # WRITE THE BODY OF clean_message HERE
  22. clean_string = ""
  23. for c in message:
  24. if c.isalpha():
  25. clean_string = clean_string + c.upper()
  26. return clean_string
  27.  
  28.  
  29. # WRITE THE REST OF YOUR A2 FUNCTIONS HERE
  30.  
  31. def encrypt_letter(letter: str, value: int) -> str:
  32. """
  33. Applies keystream value to the letter to encrpyt the letter, and returns the result.
  34.  
  35. Parameters:
  36. letter (str): Single uppercase letter to encrypt
  37. value (int): Keystream value
  38.  
  39. Returns:
  40. str: The encrypted letter
  41. """
  42. return None
  43.  
  44.  
  45. def decrypt_letter(letter: str, value: int) -> str:
  46. """
  47. Applies keystream value to the letter to decrpyt the letter, and returns the result.
  48.  
  49. Parameters:
  50. letter (str): Single uppercase letter to decrypt
  51. value (int): Keystream value
  52.  
  53. Returns:
  54. str: The decrypted letter
  55. """
  56. return None
  57.  
  58.  
  59. def is_valid_deck(deck: List[int]) -> bool:
  60. """
  61. Checks if a deck is valid (contains every integer from 1 to the number of cards in the deck)
  62.  
  63. Parameters:
  64. deck (List[int]): A candidate deck of cards
  65.  
  66. Returns:
  67. bool: True if the candidate deck is a valid deck of cards
  68. """
  69. for i in range(1, len(deck) + 1):
  70. if deck.count(i) != 1:
  71. return False
  72. return True
  73.  
  74.  
  75. def swap_cards(deck: List[int], index: int) -> None:
  76. """
  77. Swap the card at an idex with the card after it, treat deck as circular connected
  78.  
  79. Parameters:
  80. deck (List[int]): A candidate deck of cards
  81. index (int): The index at which to swap with following card
  82. """
  83. swap_index = index + 1
  84. if index == len(deck) - 1:
  85. swap_index = 0
  86. temp = deck[swap_index]
  87. deck[swap_index] = deck[index]
  88. deck[index] = temp
  89. return None
  90.  
  91.  
  92. def get_small_joker_value(deck: List[int]) -> int:
  93. """
  94. Gets the value of the smaller joker card
  95.  
  96. Parameters:
  97. deck (List[int]): A candidate deck of cards
  98.  
  99. Returns:
  100. int: The value of the small joker
  101. """
  102. max = 0
  103. for i in deck:
  104. if i > max:
  105. max = i
  106. return max - 1
  107.  
  108.  
  109. def get_big_joker_value(deck: List[int]) -> int:
  110. """
  111. Gets the value of the big joker card
  112.  
  113. Parameters:
  114. deck (List[int]): A candidate deck of cards
  115.  
  116. Returns:
  117. int: The value of the larger joker
  118. """
  119. max = 1
  120. for i in deck:
  121. if i > max:
  122. max = i
  123. return max
  124.  
  125.  
  126. def move_small_joker(deck: List[int]) -> None:
  127. """
  128. Swap the small joker with the following card, treat as circular connected
  129.  
  130. Parameters:
  131. deck (List[int]): A candidate deck of cards
  132. """
  133. swap_cards(deck, deck.index(get_small_joker_value(deck)))
  134. return None
  135.  
  136.  
  137. def move_big_joker(deck: List[int]) -> None:
  138. """
  139. Swap the big joker with the following card, treat as circular connected
  140.  
  141. Parameters:
  142. deck (List[int]): A candidate deck of cards
  143. """
  144. swap_cards(deck, deck.index(get_big_joker_value(deck)))
  145. swap_cards(deck, deck.index(get_big_joker_value(deck)))
  146. return None
  147.  
  148.  
  149. def triple_cut(deck: List[int]) -> None:
  150. """
  151. Do a triple cut on the deck
  152.  
  153. Parameters:
  154. deck (List[int]): A candidate deck of cards
  155. """
  156. s_j_index = deck.index(get_small_joker_value(deck))
  157. b_j_index = deck.index(get_big_joker_value(deck))
  158. f_j_index = s_j_index if s_j_index < b_j_index else b_j_index
  159. sd_j_index = s_j_index if s_j_index > b_j_index else b_j_index
  160. if sd_j_index == len(deck) - 1:
  161. deck[:] = deck[f_j_index:] + deck[:f_j_index]
  162. elif f_j_index == 0:
  163. deck[:] = deck[sd_j_index + 1:] + deck[:sd_j_index + 1]
  164. else:
  165. deck[:] = deck[sd_j_index+1:] + \
  166. deck[f_j_index:sd_j_index + 1] + deck[:f_j_index]
  167. return None
  168.  
  169.  
  170. def insert_top_to_bottom(deck: List[int]) -> None:
  171. """
  172. Examine the value of the bottom card and move that many cards from the top of the deck to the bottom, just above the bottom card (If bottom card is big joker, use small joker value as number of cards)
  173.  
  174. Parameters:
  175. deck (List[int]): A candidate deck of cards
  176. """
  177. bottom_index = deck[len(deck) - 1]
  178. if bottom_index == get_big_joker_value(deck):
  179. bottom_index -= 1
  180. deck[:] = deck[bottom_index:len(deck)-1] + \
  181. deck[:bottom_index]+deck[len(deck) - 1: len(deck)]
  182. return None
  183.  
  184.  
  185. def get_card_at_top_index(deck: List[int]) -> int:
  186. """
  187. Using the top value of the card as an index, return the card in the deck at that index (If top card is big joker, use small joker value as index)
  188.  
  189. Parameters:
  190. deck (List[int]): A candidate deck of cards
  191.  
  192. Returns:
  193. int: The value of the top index card
  194. """
  195. index = deck[0]
  196. if get_big_joker_value(deck) == index:
  197. index = get_small_joker_value(deck)
  198. return deck[index]
  199.  
  200.  
  201. def get_next_keystream_value(deck: List[int]) -> int:
  202. """
  203. Repeats algorithm steps until a valid keystream value is produced
  204.  
  205. Parameters:
  206. deck (List[int]): A candidate deck of cards
  207.  
  208. Returns:
  209. int: Return the valid keystream value
  210. """
  211. keystream_value = -1
  212. while keystream_value < 1 or (keystream_value == get_small_joker_value(deck) or keystream_value == get_big_joker_value(deck)):
  213. move_small_joker(deck)
  214. move_big_joker(deck)
  215. triple_cut(deck)
  216. insert_top_to_bottom(deck)
  217. keystream_value = get_card_at_top_index(deck)
  218. return keystream_value
  219.  
  220.  
  221. def process_messages(deck: List[int], messages: List[str], type: str) -> List[str]:
  222. """
  223. Process the encrypted or decrypted messages
  224.  
  225. Parameters:
  226. deck (List[int]): A candidate deck of cards
  227. message (List[str]): List of unprocessed encrypted or decrypted messages
  228. type (str): ENCRYPT or DECRYPT
  229.  
  230. Returns:
  231. List[str]: List of processed encrypted or decrypted messages
  232. """
  233. result = []
  234. if type == ENCRYPT:
  235. for i in range(0, len(messages)):
  236. message_values = []
  237. key_values = []
  238. messages[i] = clean_message(messages[i])
  239. s = ""
  240. for j in range(0, len(messages[i])):
  241. message_values.append(ord(messages[i][j]) - 64)
  242. key_values.append(get_next_keystream_value(deck))
  243. char_val = ((message_values[j] + key_values[j]) %
  244. (len(deck) - 2)) + 64
  245. if char_val == 64:
  246. char_val = len(deck) - 2 + 64
  247. print(char_val-64)
  248. s += chr(char_val)
  249. result.append(s)
  250. if type == DECRYPT:
  251. for i in range(0, len(messages)):
  252. message_values = []
  253. key_values = []
  254. messages[i] = clean_message(messages[i])
  255. s = ""
  256. for j in range(0, len(messages[i])):
  257. message_values.append(ord(messages[i][j]) - 64)
  258. key_values.append(get_next_keystream_value(deck))
  259. char_val = ((message_values[j] - key_values[j]) %
  260. (len(deck) - 2)) + 64
  261. if char_val == 64:
  262. char_val = len(deck) - 2 + 64
  263. s += chr(char_val)
  264. result.append(s)
  265. return result
  266.  
  267.  
  268. # This if statement should always be the last thing in the file, below all of
  269. # your functions:
  270. if __name__ == '__main__':
  271. """Did you know that you can get Python to automatically run and check
  272. your docstring examples? These examples are called "doctests".
  273.  
  274. To make this happen, just run this file! The two lines below do all
  275. the work.
  276.  
  277. For each doctest, Python does the function call and then compares the
  278. output to your expected result.
  279.  
  280. NOTE: your docstrings MUST be properly formatted for this to work!
  281. In particular, you need a space after each >>>. Otherwise Python won't
  282. be able to detect the example.
  283. """
  284.  
  285. import doctest
  286. doctest.testmod()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement