1) не получается сделать, чтобы выводило найденный “шаблон”(если нашли еще подстроки) по одному разу, т.е. нашло еще одну подстроку такую же - вывело один раз
2) где лучше всего расположить обработку расстояний для данного шаблона, если найдено хотя бы 2 таких подстроки (т.е. шаблон+еще найдено хотя бы раз)? где и каким образом, т.к. шаблон все-таки меняется? после строки вот этой?
if i+len_block<len(text) and text[i:i+len_block+1] == text[f:f+len_block+1]: continue
Примеры шифра:
1) AXIJZYBISCQMHSJHWSXLIEKTTRPSLTUHENTNJZNXBLSGGZWWVLWIGGGGZHLHNSIHXYZTPS
2) VHVSSPQUCEMRVBVBBBVHVSURQGIBDUGRNICJQUCERVUAXSSR
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Реализация атаки Касиского для взлома шифра Виженера Возвращает наиболее вероятную длину ключа из всех возможных """ alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" def GetString(text,offset): """ Обрезка строки, необходимой для поиска повторяющихся блоков """ return text[offset:] def findBlock(text,len_block,offset): """ Входные параметры: text - строка с зашифрованным текстом len_block - длина блока в буквах offset - смещение Совершает: - Поиск всех повторяющихся блоков в строке text, длиной len_block """ dict_NOD={} # словарь вида "Блок=НОД" lst_NOD=[] # список, хранящий вхождения блоков # ищем в строке блоки одинакового вида for i in range(len(text)-len_block): target=text[i:i+len_block] # блок, который будет ключом поиска found=text[i+len_block:].find(target) # ищем # если найден блок if found!=-1: f=found+i-len_block if i>0 and text[i-1:i+len_block] == text[f-1:f+len_block]: continue if i+len_block<len(text) and text[i:i+len_block+1] == text[f:f+len_block+1]: continue print ("%-10s %3d" % (target, found+len_block)) # возвращаем словарь с именем блока и НОД для него return dict_NOD def startAnalyze(text): """ Входные параметры: text - строка с зашифрованным текстом Совершает: - Удаление символов, не входящих в алфавит шифра - Вызов функции для поиска в строке подстроки и их добавление в словарь вида D[блок]=НОД_для_блока - Поиск НОД для всех блоков """ crText="" # корректировка строки for symbol in text: symbol=symbol.upper() # сделаем символ прописным # если символ входит в состав алфавита if symbol in alphabet: # то добавим его в "шифровку" crText+=symbol dict_={} # ищем в строке подстроку, поблочно (минимальная единица из 3 символов) for index in range(len(crText)-2): maxBlockCnt=int((len(crText)/2)-index) # максимальная длина блока для данной строки sliced=GetString(crText,index) # "обрезка" строки # совершаем поиск блока for len_block in range(3,maxBlockCnt,1): result=findBlock(sliced,len_block,index) # если словарь не пустой, то проверим содержимое if(len(result)!=0): keys=dict_.keys(); for key in keys: # проверка на вхождение блока, т.е. есть ли он в базе? if key in dict_: pass # если нет, то добавить else: dict_[key]=resut[key] # вычисляем НОД для всех блоков и определяем возможную длину ключа for key in dict_: print(key,"=",dict_[key]) if __name__ == '__main__': # вводим зашифрованную строку crText= input("Text: ") # анализ строки startAnalyze(crText)