Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

def kasiski _ diffs ( Y , case = upper ) : Y = only _ letters ( Y , case = case ) ctr

def kasiski_diffs(Y, case="upper"):
Y = only_letters(Y, case=case)
ctr = count_substrings(Y,3)
tri_reps =[k for k,v in ctr.items() if v >1]
diffs =[]
for tri in tri_reps:
starts =[m.start() for m in re.finditer(f'(?={tri})', Y)]
diffs.extend([abs(x-y) for x,y in combinations(starts,2)])
return np.array(sorted(diffs))
def ind_co(X):
X = only_letters(X, case="upper")
ctr = count_substrings(X,1)
n = sum(ctr.values())
return (1/(n*(n-1)))*sum(f*(f-1) for f in ctr.values())
* In lecture on D20240701, we used (an estimate for) the Index of Coincidence to distinguish random characters from shift ciphertext. One strength of the Vigenre cipher is that it looks very much like random text from this perspective. Compute `ind_co(Y)` for `Y` as above, and compare it with `1/26`, which is the value expected for randomly chosen English characters. (**Comment**. We've changed `ind_co` since Monday. It used to take a dictionary of letter frequencies as input, like `mut_ind_co`. Now it takes a string as input.)
* On the other hand, the above was encrypted using a Vigenre cipher with a key length of `7`. Compute the following and compare the values with the expected Index of Coincidence value for true English of approximately `0.068`.(All of the values will be close to, but slightly less than, this `0.068` value. I'm not sure if there is a theoretical reason for why they are less than `0.068`. The important thing is they're all significantly closer to the true English value than to the random characters value.)
```
Z = only_letters(Y) # we remove spaces from `Y`
for i in range(7):
print(ind_co(Z[i::7]))
```
* Write a function to perform Vigenre encryption using the following template. (If you want to make the code more elegant, replace `for i in range(key_length):` in our template with `for i, k in enumerate(key):`.)
> Input: a string `X` and a list of shift amounts `key`
> Output: a string `Y`
>
> Example: If `X` is `"The rain in Spain stays mainly in the plain"` and `key` is `[5,11,0,12,8,13,6,14]`, then the output should be the ciphertext written on page 217 of our textbook, beginning `"YSEDIVTWSDPM..."`.
```
def vigenere(X, key, case="upper"):
X = only_letters(X, case=case)
key_length = len(key)
string_list =[]
for i in range(key_length):
s = # Get the characters in `X` at integer positions ??? modulo ???
shifted_s = # Shift the characters in s. Use the imported `shift_string` function.
string_list.append(shifted_s)
output = # Use the imported `weave` function
return output
```* Test your function by evaluating the following and checking that the result matches what is on page 217 of the textbook (aside from ours being in upper-case letters).
```
X = "The rain in Spain stays mainly in the plain"
key =[5,11,0,12,8,13,6,14]
vigenere(X, key)
```

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Introduction To Data Mining

Authors: Pang Ning Tan, Michael Steinbach, Vipin Kumar

1st Edition

321321367, 978-0321321367

More Books

Students also viewed these Databases questions