This is even simpler explanation of the Birthday problem.
Such problems are abundant in textbooks about probability. A pair of dice is rolled. What is the probability that the two dice show the same number?
Three/four/etc dice are rolled. Same question.
Let's solve this by experiment. Pair of dice:
#!/usr/bin/env python3
total=0
at_least_one_pair=0
for i in range(6):
for j in range(6):
total=total+1
if i==j:
at_least_one_pair=at_least_one_pair+1
print (i, j, "one pair")
else:
print (i, j, "different")
print ("total", total)
print ("at_least_one_pair", at_least_one_pair)
print ("probability", at_least_one_pair/total)
The probability is \( \frac{1}{6} \).
3 dice?
#!/usr/bin/env python3
total=0
at_least_one_pair=0
for i in range(6):
for j in range(6):
for k in range(6):
total=total+1
if i==j or j==k or i==k:
at_least_one_pair=at_least_one_pair+1
print (i, j, k, "at least one pair")
else:
print (i, j, k, "all different")
print ("total", total)
print ("at_least_one_pair", at_least_one_pair)
print ("probability", at_least_one_pair/total)
... total 216 at_least_one_pair 96 probability 0.4444444444444444
4 dice?
#!/usr/bin/env python3
total=0
at_least_one_pair=0
for i in range(6):
for j in range(6):
for k in range(6):
for m in range(6):
total=total+1
if i==j or i==k or i==m or j==k or j==m or k==m:
at_least_one_pair=at_least_one_pair+1
print (i, j, k, m, "at least one pair")
else:
print (i, j, k, m, "all different")
print ("total", total)
print ("at_least_one_pair", at_least_one_pair)
print ("probability", at_least_one_pair/total)
... total 1296 at_least_one_pair 936 probability 0.7222222222222222
Now generalize this problem to 365-sided dice. And throw 23 such dices.
#!/usr/bin/env python3
import random
def random_lst(l, m):
return [random.randint(0, m-1) for i in range(l)]
for i in range(10000):
sample=random_lst(23, 365)
l=len(set(sample))
if l==23:
print ("all different", sample)
else:
print ("coincidences ", sample)
% python3 4.py | grep coinc | wc -l 5105
Rougly \( \frac{1}{2} \), as stated in Wikipedia
70 dices?
#!/usr/bin/env python3
import random
def random_lst(l, m):
return [random.randint(0, m-1) for i in range(l)]
for i in range(10000):
sample=random_lst(70, 365)
l=len(set(sample))
if l==70:
print ("all different", sample)
else:
print ("coincidences ", sample)
According to Wikipedia, 99.9%:
% python3 5.py | grep coinc | wc -l 9994
Now about birthday attack.

Yes, I know about these lousy Disqus ads. Please use adblocker. I would consider to subscribe to 'pro' version of Disqus if the signal/noise ratio in comments would be good enough.