Last active
August 29, 2015 14:00
-
-
Save metula/11318709 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def check_digit(id8): | |
total = 0 | |
for i in range(8): | |
val = int(id8[i]) # converts to numeric value | |
if i % 2 == 0: | |
total = total + val | |
else: | |
if val < 5: | |
total = total + 2 * val | |
else: | |
# sum of digits in 2*val | |
total = total + ((2*val) % 10) + 1 | |
total = total % 10 | |
return (10 - total) % 10 # complement mod 10 of sum | |
def verify_ID(id9): | |
return int(id9[8]) == check_digit(id9[:8]) | |
# To run the program, type ID_Check_Digit() in Python shell. | |
def ID_Check_Digit(): | |
""" compute the check digit in an Israeli ID number """ | |
# prompts for input from user | |
part_ID = input("Please type the first 8 digits of your ID: ") | |
if len(part_ID) != 8: | |
print("Must type all eight (non-check) digits of your ID.") | |
else: | |
check_digit = check_digit(part_ID) | |
print("Your ID check digit is", check_digit) | |
# Tests | |
#print(verify_ID('658118054')) | |
#print(verify_ID('658118057')) | |
import itertools | |
import math | |
def all_bits(n): | |
return itertools.product(*[(0,1)]*n) | |
def hamming_distance(x, y): | |
assert len(x) == len(y) | |
return sum(x[i] != y[i] for i in range(len(x))) | |
def ball(x, r=1): | |
return {y for y in all_bits(len(x)) if hamming_distance(x, y) <= r} | |
def min_dist(C): | |
return min({hamming_distance(x, y) for x, y in itertools.combinations(C, 2)}) | |
def hamming_encode(x3,x5,x6,x7): | |
x1 = (x3+x5+x7) % 2 | |
x2 = (x3+x6+x7) % 2 | |
x4 = (x5+x6+x7) % 2 | |
return (x1,x2,x3,x4,x5,x6,x7) | |
def hamming_decode(y1,y2,y3,y4,y5,y6,y7): | |
""" Hamming decoding of the 7 bits signal """ | |
b1 = (y1+y3+y5+y7) % 2 | |
b2 = (y2+y3+y6+y7) % 2 | |
b3 = (y4+y5+y6+y7) % 2 | |
b = 4*b3 + 2*b2 + b1 # the integer value | |
if b==0 or b==1 or b==2 or b==4: | |
return (y3, y5, y6, y7) | |
else: | |
y = [y1, y2, y3, y4, y5, y6, y7] | |
y[b-1] = (y[b-1] + 1) % 2 # correct bit b | |
return (y[2], y[4], y[5], y[6]) | |
REPETITION_C = {(x[0], x[0], x[0], x[1], x[1], x[1]) for x in all_bits(2)} | |
PARITY_C = {(x[0], x[1], x[0]^x[1]) for x in all_bits(2)} | |
HAMMING_C = {hamming_encode(*x) for x in all_bits(4)} | |
def xor(x, y): | |
assert len(x) == len(y) | |
return (x[i] ^ y[i] for i in range(len(x))) | |
def analyze_code(C, name="given"): | |
n = len(list(C)[0]) | |
k = math.log2(len(C)) | |
d = min_dist(C) | |
print("The {0} code is a ({1}, {2:.2}, {3}) code.".format(name, n, k, d)) | |
print("Rate: {0:.2}".format(k / n)) | |
print("Relative distance: {0:.2}".format(float(d) / n)) | |
print("") | |
analyze_code(REPETITION_C, "Repetition") | |
analyze_code(PARITY_C, "Parity") | |
analyze_code(HAMMING_C, "Hamming") | |
def test_hamming(): | |
failures = 0 | |
successes = 0 | |
for x in all_bits(4): | |
c = hamming_encode(*x) | |
for y in ball(c, 1): | |
if hamming_decode(*y) != x: | |
print("Error for {0}. Expected {1}".format(y, x)) | |
failures += 1 | |
else: | |
successes += 1 | |
print("Test Hamming: failures={0}, successes={1}".format(failures, successes)) | |
test_hamming() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment