Advertisement
nicoviale_

Untitled

Mar 2nd, 2024
1,211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.68 KB | None | 0 0
  1. ENGLISHFREQ = {
  2.     'A': 0.082, 'B': 0.015, 'C': 0.028, 'D': 0.043, 'E': 0.127, 'F': 0.022, 'G': 0.020,
  3.     'H': 0.061, 'I': 0.070, 'J': 0.002, 'K': 0.008, 'L': 0.040, 'M': 0.024, 'N': 0.067,
  4.     'O': 0.075, 'P': 0.019, 'Q': 0.001, 'R': 0.060, 'S': 0.063, 'T': 0.091, 'U': 0.028,
  5.     'V': 0.010, 'W': 0.023, 'X': 0.001, 'Y': 0.020, 'Z': 0.001
  6. }
  7.  
  8. ciphertext=input()
  9.  
  10. #mappa la frequenza di ogni lettera in una data stringa
  11. def frequency(ciphertext):
  12.     freq = {chr(i + ord('A')): 0 for i in range(26)}
  13.  
  14.     for char in ciphertext:
  15.         freq[char] += 1
  16.  
  17.     return freq
  18.  
  19. #taglia la stringa tenendo solo i caratteri che sono in una posizione multipla del modulo dato
  20. #(per selezionare con shift di 1 basta togliere il primo carattere e passare quello alla funzione, eccetera)
  21. def split_string(s,mod):
  22.     return s[::mod]
  23.  
  24. #ricerca nelle coppie lo shift che ha generato il lambda maggiore
  25. def find_max_M(possibili_shift):
  26.     return max(possibili_shift, key=lambda pair: pair[1])
  27.  
  28. #trova tutti gli shift e i loro relativi m, restituisce quello con l'm piu grande
  29. def get_shift_of_best_M(stringa):
  30.     n=len(stringa)
  31.  
  32.     possibili_shift=[]
  33.  
  34.     #array frequenze
  35.     frequenzaRiscontrata=[]
  36.     for key in ENGLISHFREQ:
  37.         frequenzaRiscontrata.append(stringa.count(key))
  38.  
  39.     #calcolo indice di mutua coincidenza per ogni g(shift) possibile
  40.     for g in range(0,26):    
  41.         M=0
  42.         i=0
  43.         for key,value  in ENGLISHFREQ.items():
  44.             M+=(value*frequenzaRiscontrata[(i+g)%26])/n
  45.             i+=1
  46.         possibili_shift.append((g,M))
  47.    
  48.     #trovo il maggiore shift
  49.     max_pair = find_max_M(possibili_shift)
  50.  
  51.     return(max_pair[0])
  52.  
  53.  
  54.  
  55.  
  56. #supposta lunghezza della chiave
  57. key_len = 8  #siuuuuuuu
  58.  
  59. #lista di sottostringhe
  60. substrings = []
  61.  
  62. #ricavo le sottostringhe tagliando a intervalli regolari la stringa iniziale
  63. for i in range(0,key_len):
  64.     substrings.append(split_string(ciphertext[i:],key_len))
  65.  
  66. print(substrings)
  67.  
  68. #stampo le frequenze per ogni substring(non utilizzato ma utile per debug)
  69. freq_list = [(frequency(substring)) for substring in substrings]
  70.  
  71. print(freq_list)
  72.  
  73. shift_list=[0]*key_len
  74.  
  75. #calcolo lo shift migliore per ogni sottostringa
  76. for i in range(0,key_len):
  77.     shift_list[i]=get_shift_of_best_M(substrings[i])
  78.  
  79. print(shift_list)
  80.  
  81.  
  82. #chr(65) -> A
  83. #ord('a')-> 97
  84.  
  85. final_array=['*']*len(ciphertext)
  86. i=0
  87. #ciclo ogni lettera e faccio la sostituzione con la relativa chiave
  88. for letter in ciphertext:
  89.     final_array[i]=chr(ord('A')+ (ord(letter)-ord('A')-shift_list[i%key_len])%26)
  90.     i+=1
  91.  
  92. #converto l'array in una stringa per la stampa finale
  93. stringa_output= ''.join(final_array)
  94.  
  95. print(stringa_output)
  96.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement