Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ENGLISHFREQ = {
- 'A': 0.082, 'B': 0.015, 'C': 0.028, 'D': 0.043, 'E': 0.127, 'F': 0.022, 'G': 0.020,
- 'H': 0.061, 'I': 0.070, 'J': 0.002, 'K': 0.008, 'L': 0.040, 'M': 0.024, 'N': 0.067,
- 'O': 0.075, 'P': 0.019, 'Q': 0.001, 'R': 0.060, 'S': 0.063, 'T': 0.091, 'U': 0.028,
- 'V': 0.010, 'W': 0.023, 'X': 0.001, 'Y': 0.020, 'Z': 0.001
- }
- ciphertext=input()
- #mappa la frequenza di ogni lettera in una data stringa
- def frequency(ciphertext):
- freq = {chr(i + ord('A')): 0 for i in range(26)}
- for char in ciphertext:
- freq[char] += 1
- return freq
- #taglia la stringa tenendo solo i caratteri che sono in una posizione multipla del modulo dato
- #(per selezionare con shift di 1 basta togliere il primo carattere e passare quello alla funzione, eccetera)
- def split_string(s,mod):
- return s[::mod]
- #ricerca nelle coppie lo shift che ha generato il lambda maggiore
- def find_max_M(possibili_shift):
- return max(possibili_shift, key=lambda pair: pair[1])
- #trova tutti gli shift e i loro relativi m, restituisce quello con l'm piu grande
- def get_shift_of_best_M(stringa):
- n=len(stringa)
- possibili_shift=[]
- #array frequenze
- frequenzaRiscontrata=[]
- for key in ENGLISHFREQ:
- frequenzaRiscontrata.append(stringa.count(key))
- #calcolo indice di mutua coincidenza per ogni g(shift) possibile
- for g in range(0,26):
- M=0
- i=0
- for key,value in ENGLISHFREQ.items():
- M+=(value*frequenzaRiscontrata[(i+g)%26])/n
- i+=1
- possibili_shift.append((g,M))
- #trovo il maggiore shift
- max_pair = find_max_M(possibili_shift)
- return(max_pair[0])
- #supposta lunghezza della chiave
- key_len = 8 #siuuuuuuu
- #lista di sottostringhe
- substrings = []
- #ricavo le sottostringhe tagliando a intervalli regolari la stringa iniziale
- for i in range(0,key_len):
- substrings.append(split_string(ciphertext[i:],key_len))
- print(substrings)
- #stampo le frequenze per ogni substring(non utilizzato ma utile per debug)
- freq_list = [(frequency(substring)) for substring in substrings]
- print(freq_list)
- shift_list=[0]*key_len
- #calcolo lo shift migliore per ogni sottostringa
- for i in range(0,key_len):
- shift_list[i]=get_shift_of_best_M(substrings[i])
- print(shift_list)
- #chr(65) -> A
- #ord('a')-> 97
- final_array=['*']*len(ciphertext)
- i=0
- #ciclo ogni lettera e faccio la sostituzione con la relativa chiave
- for letter in ciphertext:
- final_array[i]=chr(ord('A')+ (ord(letter)-ord('A')-shift_list[i%key_len])%26)
- i+=1
- #converto l'array in una stringa per la stampa finale
- stringa_output= ''.join(final_array)
- print(stringa_output)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement