# Quiz 3 ## Program Description ### Part 1 - Calculating IC 1. By iterating through all the possible IC, calculate the IC of the current keylength for the groups. ```python= for i in range(4, 8, 1): # Constructing the groups for the keylength grouping = [] for j in range(i): grouping.append([]) # Put them into groups by their index for j in range(len(text)): grouping[j % i].append(text[j]) ic = np.zeros(i) sum = np.zeros(i) # For each group, calculate the IC and the total number of alphebets in the group for j in range(i): cipher = Counter(grouping[j]) ic2 = 0 sum2 = 0 for k in cipher.most_common(): ic[j] += k[1] * (k[1] - 1) sum[j] += k[1] # After the iteration, calculate the sum value of the IC group ic[j] = ic[j] / (sum[j] * (sum[j] - 1)) # The value would be the average if maxIC < np.average(ic): maxIC = np.average(ic) keyLength = i ``` 2. For each group, we need to calculate the possible decryption key. By trying all the combinations, decrypt it using the one tried and calculate the appearance distance with the mornal plaintext. Finally obtain the smallest difference ```python= # Construct the dcryption for all the group decipherKey = "" grouping = [] for j in range(keyLength): grouping.append([]) for j in range(len(text)): grouping[j % keyLength].append(text[j]) # For each group, go through all possibilities and try to decipher using the target for j in range(keyLength): cipher = Counter(grouping[j]) ic = np.zeros(26) # Iterate through combination for k in range(26): for idx, val in cipher.most_common(): # Get the decipher value decipher = ord(idx) - 65 - k if decipher < 0: decipher += 26 # Calculate the distance between the appearance of real plaintext and the target ic[k] += pow(val - apperance[decipher], 2) / (apperance[decipher]) # Get the smallest one among IC for idx, val in enumerate(ic): if val == min(ic): decipherKey += chr(idx + 65) ``` 3. By turning it into plaintext, use the decrypt key ```python= plain = "" for j in range(len(text)): # Use modulus to get the key for that index decipher = ord(text[j]) - ord(decipherKey[j % keyLength]) if decipher < 0: decipher += 26 # Restore is back using the key plain += chr(decipher + 65) print(plain) ``` ## Bonus 2 不是,因為完美密碼每送一次都必須更換密鑰(也就是所謂的亂數)但是RSA 的公私鑰是不變的,所以不能稱為完美密碼。