In [1]:
"""
Some masks and the number of 16 bit words
in our code, in this case, its 8. After
we "sythesize" the other "strand of RNA
code", we will have 8, 32 bit words, which
as a whole is analogous to DNA.
"""
L_MASK = int('0x0000ffff', 16)
H_MASK = int('0xffff0000', 16)
ERBITS = int('0xffff0000', 16)
NLINES = 8
NERROR = NLINES - 1
In [2]:
"""
Basically some aliases to avoid ( ((( ))) )
"""
fixRight = lambda x: x >> 16
fixLeft = lambda x: x << 16
In [3]:
"""
Set up some commands for generating (pseudo) random
16 bit code words and the complementary "strand of
RNA code".
riskyProc() is some simple case of a set of procedures,
operations, or coditions, (such as transmittion, storage,
recovery)
"""
from random import randint
KEY = randint(1, 2**16)
randCode = lambda : randint(0,2**16) # Generate a random code within 16 bit range
genCodePair = lambda code: (fixLeft(code ^ KEY) & H_MASK) + ( code & L_MASK ) # Generate the Complement ("hRNA + lRNA = DNA")
unZip = lambda prog: [(fixRight(x & H_MASK), x & L_MASK) for x in prog]
printBin32 = lambda x: bin(x)[2:].zfill(32) # Convert x to a binary string
printBin16 = lambda x: bin(x)[2:].zfill(16) # dido
def riskyProc(prog):
rN = randint(0,len(prog)-1)
prog[rN] = prog[rN] & ERBITS
In [4]:
"""
dispCode() takes a code list (whole_code_list) and displays it
after checking the code for errors, if there are errors, a notice
is displayed too.
"""
def dispCode(whole_code_list):
tup_list = unZip(whole_code_list)
x = [(printBin32(whole_code_list[x]) ,(printBin16(tup_list[x][0]), printBin16(tup_list[x][1]) ) ) for x in range(len(tup_list))]
for l in x:
ls_int = int('0b' + l[1][0],2)
rs_int = int('0b' + l[1][1],2)
if KEY ^ ls_int == rs_int:
print l
else:
print l, "<----- ERROR", (ls_int, rs_int, KEY ^ ls_int), "(a, b, a ^ b)"
print "\n"
Prog = [genCodePair(randCode()) for x in range(NLINES)] # Generate a program (Prog) in this case.
backUp = [int(i) for i in Prog] # Make back up
print "Good code:"
dispCode(Prog)
for i in range(NERROR):
riskyProc(Prog)
print "Bad code:"
dispCode(Prog)
In [5]:
def healCode(tup_list, key):
Prog = []
for i in range(len(tup_list)):
if key ^ tup_list[i][0] != tup_list[i][1]:
"""
Need to determine if error is on left or right (higher or lower signifcant bits)
# Some algebra
[1] a1 ^ b1 = x
[2] a2 ^ b2 = x
[3] a1 ^ x = b1
[4] b1 ^ x = a1
[5] a1 ^ b1 = a2 ^ b2
[6] a1 ^ (a2 ^ b2) = b1 "[2], [3]"
[7] b1 ^ (a2 ^ b2) = a1 "[2], [4]"
For now, I know the error is on the right....
edge-case: What if error in both side?
- We know that key stores information about all variables.
- All variables and their correct complements encode the key.
- Things are tied together, look for a way to find a1 and b1 given
a1' and b1' such that a1' is a1 with error and b1' is b1 with error.
- QUESTION: Say -> a1' ^ b1' = x'; does x' encode information about
the error in a1' and b1'? What is x ^ x'?
"""
a1, b1 = tup_list[i]
a2, b2 = None, None
if i > 0:
a2, b2 = tup_list[i-1]
elif len(tup_list) > 1:
for j in range(len(tup_list)-1):
if j == i:
continue
elif key ^ tup_list[j][0] == tup_list[j][1]:
a2, b2 = tup_list[j]
break
else:
raise Exception()
tup_list[i] = ( a1, a1 ^ (a2 ^ b2) ) # [6] (a1, b1) = (a1 , a1 ^ (a2, b2))
Prog.append(fixLeft(tup_list[i][0]) + tup_list[i][1])
return Prog
Prog = healCode(unZip(Prog), KEY)
print "Healed code"
dispCode(Prog)
print "Original code"
dispCode(backUp)
print "Healed code == Original code :", Prog == backUp
In [ ]: