Friday is project selection day! We'll go over the possible projects then. You'll have a little time to think about it before selecting one. Please send me or post on Blackboard your project selection ideas!
We'll be discussing setting up project files (instead of just using notebooks) on that day too, probably.
Posted on Blackboard.
import numpy as np
import matplotlib.pyplot as plt
Most of what we'll be covering is "random numbers" for data science, not cryptography.
def lin_cong(c, a, M, r_i):
return (a * r_i + c) % M
lin_cong(c=1, a=4, M=9, r_i=3)
lin_cong(c=1, a=4, M=9, r_i=4)
def iterator():
yield 1
yield 2
yield 3
for item in iterator():
print(item)
tuple(iterator())
def lin_cong_iter(c, a, M, r_0):
r_i = r_0
while True:
yield r_i
r_i = lin_cong(c, a, M, r_i)
if r_i == r_0:
return
list(lin_cong_iter(1, 4, 9, 3))
list(i / 8 for i in lin_cong_iter(1, 4, 9, 3))
Try it out:
Set a=57, c=1, M=256, r_0=10
(like in the book) and see what happens.
vals = list(lin_cong_iter(a=57, c=1, M=256, r_0=10))
print(len(vals))
real_rand = np.random.randint(0, 256, 256)
fig, axs = plt.subplots(1, 2, figsize=(12, 4))
axs[0].plot(vals[::2], vals[1::2], "+")
axs[1].plot(real_rand[::2], real_rand[1::2], "+")
plt.show()
fig, axs = plt.subplots(1, 2, figsize=(16, 4))
axs[0].plot(range(256), vals, "x-")
axs[1].plot(range(256), real_rand, "x-")
plt.show()
Since the book mentions Python's random numbers, let's look at that first. Once you know how they work, it really doesn't matter which library you use except for speed and simplicity (and then go with Numpy, of course).
import random
random.seed(42)
for i in range(10):
print(random.randint(0, 256))
Let's try the same with Numpy:
np.random.seed(42)
np.random.randint(0, 256, 10)
state1 = np.random.RandomState(42)
state1.randint(0, 256)
np.random.seed(42)
rsamp = np.random.rand(1000)
rsamp[:100]
plt.plot(rsamp, ".")
N = len(rsamp)
moment1 = 1 / N * np.sum(rsamp ** 1)
moment2 = 1 / N * np.sum(rsamp ** 2)
moment3 = 1 / N * np.sum(rsamp ** 3)
print(f"moment 1: {moment1} == {1/(1+1)} +/- {1/np.sqrt(N)}")
print(f"moment 2: {moment2} == {1/(1+2)} +/- {1/np.sqrt(N)}")
print(f"moment 3: {moment3} == {1/(1+3)} +/- {1/np.sqrt(N)}")
np.roll(np.arange(10), -2)
1 / N * np.sum(rsamp * np.roll(rsamp, 1))
1 / N * np.sum(rsamp * np.roll(rsamp, 2))
1 / N * np.sum(rsamp * np.roll(rsamp, 3))
1 / N * np.sum(rsamp * np.roll(rsamp, 4))
fig, ax = plt.subplots()
ax.plot(rsamp[::2], rsamp[1::2], "+")
plt.show()