added exam exercise 19
This commit is contained in:
parent
4097f8e010
commit
d9148e64fe
32
exam/ex19/caesar.py
Normal file
32
exam/ex19/caesar.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
|
||||||
|
def internal_ord(c):
|
||||||
|
c = c.lower()
|
||||||
|
internal_ord = ord(c) - ord("a")
|
||||||
|
if(internal_ord < 0 or internal_ord > 25):
|
||||||
|
raise ValueError("'{}' is an unsupported character".format(c))
|
||||||
|
return internal_ord
|
||||||
|
|
||||||
|
def internal_chr(i):
|
||||||
|
return chr(ord("a") + i)
|
||||||
|
|
||||||
|
|
||||||
|
def encode_or_keeps_space(c):
|
||||||
|
if(c == " "):
|
||||||
|
return (False, c)
|
||||||
|
return (True, internal_ord(c))
|
||||||
|
|
||||||
|
def prepare_string(s):
|
||||||
|
return (encode_or_keeps_space(c) for c in s)
|
||||||
|
|
||||||
|
|
||||||
|
def _caesar(s, K):
|
||||||
|
for encode, i in prepare_string(s):
|
||||||
|
if(encode):
|
||||||
|
yield internal_chr((i + K) % 26)
|
||||||
|
else:
|
||||||
|
yield i
|
||||||
|
|
||||||
|
def caesar(s, K):
|
||||||
|
return "".join(_caesar(s, K))
|
||||||
|
|
21
exam/ex19/main.py
Normal file
21
exam/ex19/main.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from caesar import caesar
|
||||||
|
from statistical_attack import get_statistical_key
|
||||||
|
|
||||||
|
text1 = "hello world this is a test"
|
||||||
|
text2 = "this is a message that is obfuscated"
|
||||||
|
|
||||||
|
K2 = 4
|
||||||
|
K1 = 13
|
||||||
|
|
||||||
|
print(caesar(text1, K1))
|
||||||
|
print(caesar(caesar(text1, K1), K1))
|
||||||
|
|
||||||
|
print(caesar(text2, K2))
|
||||||
|
print(caesar(caesar(text2, K2), abs(K2 - 26)))
|
||||||
|
|
||||||
|
text4 = "In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence"
|
||||||
|
|
||||||
|
text4 = "".join((s for s in text4 if s in " abcdefghijklmnopqrstuvwxyz"))
|
||||||
|
|
||||||
|
print(get_statistical_key(caesar(text4, K2)))
|
||||||
|
print(get_statistical_key(caesar(text2, K2)))
|
12326
exam/ex19/sample.tx
Normal file
12326
exam/ex19/sample.tx
Normal file
File diff suppressed because it is too large
Load Diff
29
exam/ex19/statistical_attack.py
Normal file
29
exam/ex19/statistical_attack.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
reference = Counter((c for c in open("sample.tx").read().lower() if c in alphabet))
|
||||||
|
|
||||||
|
def get_statistics(text):
|
||||||
|
return Counter([c for c in text.lower() if c in alphabet])
|
||||||
|
|
||||||
|
def relative_most_common(statistics):
|
||||||
|
c, abs_probability = statistics.most_common(1)[0]
|
||||||
|
|
||||||
|
total_chrs = sum([v for k,v in statistics.most_common()])
|
||||||
|
return abs_probability / total_chrs
|
||||||
|
|
||||||
|
|
||||||
|
def get_statistical_key(text):
|
||||||
|
statistics = get_statistics(text)
|
||||||
|
|
||||||
|
quality = relative_most_common(statistics) / relative_most_common(reference)
|
||||||
|
|
||||||
|
c, abs_probability = statistics.most_common(1)[0]
|
||||||
|
|
||||||
|
K = abs(ord("e") - ord(c))
|
||||||
|
|
||||||
|
if(quality > 1):
|
||||||
|
quality = relative_most_common(reference) / relative_most_common(statistics)
|
||||||
|
|
||||||
|
return K, quality
|
Loading…
Reference in New Issue
Block a user