Advertisement
vana_shimko

Vigenere + Kasiski ne rabotaet

Sep 3rd, 2015
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.16 KB | None | 0 0
  1. alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
  2.  
  3. def CreateKey(text, keyword):
  4.     key = [None] * len(text)
  5.     alphabeticalCharsCount = 0
  6.     keyword = keyword.upper()
  7.     for i in range(len(text)):
  8.         if text[i].upper() in alphabet:
  9.             key[i] = alphabet[(alphabet.find(keyword[alphabeticalCharsCount % len(keyword)]) + ( alphabeticalCharsCount // len(keyword) )) % len(alphabet)]
  10.             alphabeticalCharsCount += 1
  11.         else:
  12.             key[i] = ' '
  13.            
  14.     return key
  15.  
  16.  
  17. def CipherText(plaintext, keyword):
  18.     key = CreateKey(plaintext, keyword)
  19.     cipheredText = [None] * len(plaintext)
  20.     plaintext = plaintext.upper()
  21.    
  22.     for i, c in enumerate(plaintext):
  23.         if plaintext[i].upper() in alphabet:
  24.             cipheredText[i] = alphabet[(alphabet.find(c) + alphabet.find(key[i])) % len(alphabet)]
  25.         else:
  26.             cipheredText[i] = plaintext[i]
  27.    
  28.     return ''.join(cipheredText)
  29.  
  30. def DecipherText(cipheredText, keyword):
  31.     key = CreateKey(cipheredText, keyword)
  32.     plaintext = [None] * len(cipheredText)
  33.     cipheredText = cipheredText.upper()
  34.    
  35.     for i, c in enumerate(cipheredText):
  36.         if cipheredText[i].upper() in alphabet:
  37.             plaintext[i] = alphabet[(alphabet.find(c) - alphabet.find(key[i])) % len(alphabet)]
  38.         else:
  39.             plaintext[i] = cipheredText[i]
  40.    
  41.     return ''.join(plaintext)
  42.  
  43. def RemoveNonAlpha(pattern):
  44.     return ''.join([x for x in pattern if x in alphabet])
  45.  
  46. def GetCharsDelta(c1, c2):
  47.     return abs(ord(c1) - ord(c2))
  48.  
  49. def CheckPatterns(p1, p2):
  50.     delta = GetCharsDelta(p1[0], p2[0])
  51.     for i in range(1, len(p1)):
  52.         if delta != GetCharsDelta(p1[i], p2[i]):
  53.             break
  54.     else:
  55.         return True
  56.    
  57.     return False
  58.    
  59. def GetGCD(a, b):
  60.     while b:
  61.         a, b = b, a % b
  62.     return a
  63.    
  64. def ProcessDeltas(deltasList):
  65.     gcd = GetGCD(deltasList[0], deltasList[1])
  66.     for currentDelta in deltasList[2:]:
  67.         gcd = GetGCD(gcd, currentDelta)
  68.        
  69.     return gcd
  70.  
  71. def IsNewPattern(patternsDict, pattern):
  72.     for x in patternsDict:
  73.         if CheckPatterns(x, pattern):
  74.             break
  75.     else:
  76.         return True
  77.    
  78.     return False
  79.    
  80. def GetDeltas(patterns):
  81.     deltas = {}
  82.     for patternInfo in patterns.items():
  83.         patternList = patternInfo[1]
  84.        
  85.         previousPosition = patternList[0]
  86.         tmpList = []
  87.        
  88.         for currentPosition in patternList[1:]:
  89.             tmpList.append(currentPosition - previousPosition)
  90.             previousPosition = currentPosition
  91.            
  92.         deltas[patternInfo[0]] = tmpList
  93.        
  94.     return deltas
  95.  
  96. def Kasiski(cipheredText, patternLen):
  97.     patterns = {}
  98.     i = 0
  99.     cipheredText = RemoveNonAlpha(cipheredText)
  100.     while i < len(cipheredText) - patternLen:
  101.         currentPattern = cipheredText[i:i + patternLen]
  102.        
  103.         if IsNewPattern(patterns, currentPattern):
  104.             patterns[currentPattern] = []
  105.             currentPatternEntries = patterns[currentPattern]
  106.             patterns[currentPattern].append(i)
  107.            
  108.             currentPatternEntries = patterns[currentPattern]
  109.            
  110.             j = i + patternLen - 1
  111.             while j < len(cipheredText) - patternLen:
  112.                 if CheckPatterns(currentPattern, cipheredText[j:j + patternLen]):
  113.                     currentPatternEntries.append(j)
  114.                 j += 1
  115.  
  116.             if len(currentPatternEntries) < 3:
  117.                 patterns.pop(currentPattern)
  118.         i += 1
  119.    
  120.     return patterns
  121.    
  122. def GetGCDs(deltas):
  123.     GCDs = {}
  124.     for pattern in deltas:
  125.         gcd = ProcessDeltas(deltas[pattern])
  126.         if gcd != 1:
  127.             GCDs[pattern] = ProcessDeltas(deltas[pattern])
  128.     return GCDs
  129.    
  130. def GetKeyLength(gcdsList):
  131.     tmpDict = {}
  132.    
  133.     for gcd in gcdsList.values():
  134.         if gcd in tmpDict:
  135.             tmpDict[gcd] += 1
  136.         else:
  137.             tmpDict[gcd] = 1
  138.    
  139.     if tmpDict:
  140.         return max(tmpDict.items(), key = lambda x: x[1])[0]
  141.     else:
  142.         return -1
  143.  
  144. plainText = input('Text ')
  145. keyword = input('Keyword ')
  146. cipheredText = CipherText(plainText, keyword)
  147. print(cipheredText)
  148. print(DecipherText(cipheredText, keyword))
  149. for patternLen in range(3, 11):
  150.     patterns = Kasiski(cipheredText, patternLen)
  151.    
  152.     print('patterns')
  153.     for p in patterns:
  154.         print(p, patterns[p], sep = '')
  155.    
  156.     deltas = GetDeltas(patterns)
  157.     gcds = GetGCDs(deltas)
  158.    
  159.     print('gcds')
  160.     for gcd in gcds:
  161.         print(gcd, gcds[gcd], sep = ' ')
  162.     input('Press enter\n\n')
  163.    
  164.     probableKey = GetKeyLength(GetGCDs(deltas))
  165.     if probableKey != -1 and 2 < probableKey < 20:
  166.         for x in deltas:
  167.             print(x, deltas[x], sep = ' - ')
  168.         print(probableKey)
  169.         break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement