Python. Взлом шифров. Продолжение-2.
На прошлом уроке мы написали функцию сопоставления слов. Сегодня продолжим эту тему. Допустим, у нас есть некий текст в котором нам надо найти место наилучше подходящее под это слово. Пишем вот такой код:
s="вапжуоваппробавапавпавпав" i=0 w="проба" min_res=999999999999999999999 min_word="" while i<len(s)-len(w): j=0 w1="" while j<len(w): w1=w1+s[i+j] j=j+1 res=matching_word(w,w1) if res<min_res: min_res=res min_word=w1 i=i+1 print("Минимальный результат "+str(min_res)) print("Найденное слово "+min_word)
Программа сообщит:
Минимальный результат 0
Найденное слово проба
Заменим в строке
s="вапжуоваппробавапавпавпав"
слово «проба» на слово «прога» и получим уже вот такой результат:
Минимальный результат 73
Найденное слово прога
Теперь попробуем поискать словом во всем файле:
f_matching = open("d:\9\match1.txt", "r") #файл с сопоставлением словарей f_text = open("d:\9\some2.txt", "r") #файл с предобработанным текстом dic={} #словарь #Прочитаем файл сопоставлений и создадим словарь for line in f_matching: ls=line.split("^") if len(ls)>2: c=ls[0] dic=ls[2] ls=list(dic.items()) def search_simbol(s): i=0 while i<len(ls): if ls[i][0]==s: return i i=i+1 return -1 def matching_word(w1,w2): i=0 res=0 while i<len(w1): dif=0 if w1[i]!=w2[i]: ind1=search_simbol(w1[i]) ind2=search_simbol(w2[i]) if ind1==-1 or ind2==-1: dif=len(ls)+1 else: dif=abs(ind1-ind2) res=res+dif i=i+1 return res #Прочитаем файл с предобработанным текстом и в каждой строке будем искать слово w="Глава" for s in f_text: i=0 min_res=999999999999999999999 min_word="" while i<len(s)-len(w): j=0 w1="" while j<len(w): w1=w1+s[i+j] j=j+1 res=matching_word(w,w1) if res<min_res: min_res=res min_word=w1 if min_res==0: break i=i+1 print("Минимальный результат "+str(min_res)) print("Найденное слово "+min_word)
И тут я напоролся на грабли. Я специально привел код с ошибкой, чтобы рассказать об этих граблях. Итак, если вы запустите файл несколько раз, то каждый раз будете получать разные результаты! Сначала я не мог понять, почему так происходит. Затем выполнил вот такой код:
f_matching = open("d:\9\match1.txt", "r") #файл с сопоставлением словарей f_text = open("d:\9\some2.txt", "r") #файл с предобработанным текстом dic={} #словарь #Прочитаем файл сопоставлений и создадим словарь - список for line in f_matching: ls=line.split("^") if len(ls)>2: c=ls[0] dic=ls[2] print(dic)
И увидел, что каждый раз порядок ключей в словаре разный. Глюк можно исправить, если вместо словаря загружать буквы сразу в список:
f_matching = open("d:\9\match1.txt", "r") #файл с сопоставлением словарей f_text = open("d:\9\some2.txt", "r") #файл с предобработанным текстом #Прочитаем файл сопоставлений и создадим словарь - список ls=[] #Создаем список for line in f_matching: ls_line=line.split("^") if len(ls_line)>2: c=ls_line[0] ls.append(c) def search_simbol(s): i=0 while i<len(ls): if ls[i]==s: return i i=i+1 return -1 def matching_word(w1,w2): i=0 res=0 while i<len(w1): dif=0 if w1[i]!=w2[i]: ind1=search_simbol(w1[i]) ind2=search_simbol(w2[i]) if ind1==-1 or ind2==-1: dif=len(ls)+1 else: dif=abs(ind1-ind2) res=res+dif i=i+1 return res #Прочитаем файл с пробрбаботанным текстом и в каждой строке будем искать слово word="Глава" min_res=999999999999999999999 min_word="" for s in f_text: i=0 while i<len(s)-len(word): j=0 word1="" while j<len(word): word1=word1+s[i+j] j=j+1 res=matching_word(word,word1) if res<min_res: min_res=res min_word=word1 print(min_word+" "+str(min_res)) if min_res==0: break i=i+1 print("Минимальный результат "+str(min_res)) print("Найденное слово "+min_word) f_text.close()
Теперь можно подставлять слова из полученного на предыдущем этапе списка слов, начиная с верха списка, где у нас наиболее часто встречающиеся слова. Например, нас слово «Глава» у меня выдало вот такой результат:
Минимальный результат 29
Найденное слово кзала
На слово «Девушка» вот такой:
Минимальный результат 73
Найденное слово девушка
А вот такие слова как «как», «что» уже присутствуют в расшифрованном виде, то есть, по ним выдало, что расхождение 0.
Такой поиск ничего не дал, поэтому попробуем альтернативный вариант, который мы отвергли вначале: смотреть только по количеству различных букв.
Тогда функция сопоставления слов будет выглядеть вот так:
def matching_word_v2(w1,w2): i=0 res=0 while i<len(w1): dif=0 if w1[i]!=w2[i]: dif=dif+1 res=res+dif i=i+1 return res
Теперь попробуем точно также поискать слово «Глава». Находим «става». Но, как оказалось, это всего лишь часть слова «оставалось»:
Так идем, проверяя все слова из списка. На слове «Сначала» мы находим слово «фначала». Это что-то уже похожее на правду. Смотрим:
Сразу видим, что кроме замены «С» <-> «ф», можно сделать замены «ж» <-> «х», а также «б» <-> «.»
И получаем уже вот такой выходной результат:
Как видим, задача полной автоматизации расшифровки текста, даже самого простого, далеко не тривиальна. Но, в полуручном-полуавтоматическом режиме она решаема. Для автоматизации тех подходов, которые мы изучили в данном цикле уроком, необходимо освоить различные примеры работы с текстом, чем мы с вами займемся в будущих уроках.
Comments
So empty here ... leave a comment!