Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
- def CreateKey(text, keyword):
- key = [None] * len(text)
- alphabeticalCharsCount = 0
- keyword = keyword.upper()
- for i in range(len(text)):
- if text[i].upper() in alphabet:
- key[i] = alphabet[(alphabet.find(keyword[alphabeticalCharsCount % len(keyword)]) + ( alphabeticalCharsCount // len(keyword) )) % len(alphabet)]
- alphabeticalCharsCount += 1
- else:
- key[i] = ' '
- return key
- def CipherText(plaintext, keyword):
- key = CreateKey(plaintext, keyword)
- cipheredText = [None] * len(plaintext)
- plaintext = plaintext.upper()
- for i, c in enumerate(plaintext):
- if plaintext[i].upper() in alphabet:
- cipheredText[i] = alphabet[(alphabet.find(c) + alphabet.find(key[i])) % len(alphabet)]
- else:
- cipheredText[i] = plaintext[i]
- return ''.join(cipheredText)
- def DecipherText(cipheredText, keyword):
- key = CreateKey(cipheredText, keyword)
- plaintext = [None] * len(cipheredText)
- cipheredText = cipheredText.upper()
- for i, c in enumerate(cipheredText):
- if cipheredText[i].upper() in alphabet:
- plaintext[i] = alphabet[(alphabet.find(c) - alphabet.find(key[i])) % len(alphabet)]
- else:
- plaintext[i] = cipheredText[i]
- return ''.join(plaintext)
- def RemoveNonAlpha(pattern):
- return ''.join([x for x in pattern if x in alphabet])
- def GetCharsDelta(c1, c2):
- return abs(ord(c1) - ord(c2))
- def CheckPatterns(p1, p2):
- delta = GetCharsDelta(p1[0], p2[0])
- for i in range(1, len(p1)):
- if delta != GetCharsDelta(p1[i], p2[i]):
- break
- else:
- return True
- return False
- def GetGCD(a, b):
- while b:
- a, b = b, a % b
- return a
- def ProcessDeltas(deltasList):
- gcd = GetGCD(deltasList[0], deltasList[1])
- for currentDelta in deltasList[2:]:
- gcd = GetGCD(gcd, currentDelta)
- return gcd
- def IsNewPattern(patternsDict, pattern):
- for x in patternsDict:
- if CheckPatterns(x, pattern):
- break
- else:
- return True
- return False
- def GetDeltas(patterns):
- deltas = {}
- for patternInfo in patterns.items():
- patternList = patternInfo[1]
- previousPosition = patternList[0]
- tmpList = []
- for currentPosition in patternList[1:]:
- tmpList.append(currentPosition - previousPosition)
- previousPosition = currentPosition
- deltas[patternInfo[0]] = tmpList
- return deltas
- def Kasiski(cipheredText, patternLen):
- patterns = {}
- i = 0
- cipheredText = RemoveNonAlpha(cipheredText)
- while i < len(cipheredText) - patternLen:
- currentPattern = cipheredText[i:i + patternLen]
- if IsNewPattern(patterns, currentPattern):
- patterns[currentPattern] = []
- currentPatternEntries = patterns[currentPattern]
- patterns[currentPattern].append(i)
- currentPatternEntries = patterns[currentPattern]
- j = i + patternLen - 1
- while j < len(cipheredText) - patternLen:
- if CheckPatterns(currentPattern, cipheredText[j:j + patternLen]):
- currentPatternEntries.append(j)
- j += 1
- if len(currentPatternEntries) < 3:
- patterns.pop(currentPattern)
- i += 1
- return patterns
- def GetGCDs(deltas):
- GCDs = {}
- for pattern in deltas:
- gcd = ProcessDeltas(deltas[pattern])
- if gcd != 1:
- GCDs[pattern] = ProcessDeltas(deltas[pattern])
- return GCDs
- def GetKeyLength(gcdsList):
- tmpDict = {}
- for gcd in gcdsList.values():
- if gcd in tmpDict:
- tmpDict[gcd] += 1
- else:
- tmpDict[gcd] = 1
- if tmpDict:
- return max(tmpDict.items(), key = lambda x: x[1])[0]
- else:
- return -1
- plainText = input('Text ')
- keyword = input('Keyword ')
- cipheredText = CipherText(plainText, keyword)
- print(cipheredText)
- print(DecipherText(cipheredText, keyword))
- for patternLen in range(3, 11):
- patterns = Kasiski(cipheredText, patternLen)
- print('patterns')
- for p in patterns:
- print(p, patterns[p], sep = '')
- deltas = GetDeltas(patterns)
- gcds = GetGCDs(deltas)
- print('gcds')
- for gcd in gcds:
- print(gcd, gcds[gcd], sep = ' ')
- input('Press enter\n\n')
- probableKey = GetKeyLength(GetGCDs(deltas))
- if probableKey != -1 and 2 < probableKey < 20:
- for x in deltas:
- print(x, deltas[x], sep = ' - ')
- print(probableKey)
- break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement