forked from muccc/iridium-toolkit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbch.py
executable file
·147 lines (124 loc) · 3.56 KB
/
bch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python3
# vim: set ts=4 sw=4 tw=0 et pm=:
from .fec import stringify, listify
def nndivide(poly,num): # both args as int
if(num==0):
return 0
bits=num.bit_length()-poly.bit_length()
pow=1<<(num.bit_length()-1)
while bits>=0:
if (num>=pow):
num^=(poly<<bits)
pow>>=1
bits-=1
return num
def ndivide(poly,bits):
num=int(bits,2)
return nndivide(poly,num)
def divide(a,b): # returns b%a in GF(2) fast/binary version
return nndivide(int(a,2),int(b,2))
def sdivide(a,b): # returns b%a in GF(2) slow/ascii version
aa=listify (a);
bb=listify (b);
while True:
try:
one=bb.index(1);
except:
return 0;
# print "lb-o: ",len(bb)-one,"la",len(aa)
if(len(bb)-one<len(aa)):
break
# print "b: ",stringify(bb),one
# print "a: ",(" "*(one-1)),stringify(aa)
for i in range(len(a)):
if aa[i]==1:
bb[one+i]=1-bb[one+i]
# print "i: %2d"%i,stringify(bb),"a=",aa[i]
# print "b: ",stringify(bb),one
# print "Result: ",stringify(bb)
return int(stringify(bb),2)
def add(a,b): # unneccessary, as actually add(a,b) == a^b
aa=listify(a)
bb=listify(b)
result=[]
if (len(bb)>len(aa)):
(aa,bb)=(bb,aa)
for i in range(len(aa)):
result[i]=(aa[i]+bb[i])%2
return stringify(result)
def multiply(a,b):
result=0
idx=0
while (b>0):
if (b%2):
result=result^(a<<idx)
b>>=1
idx+=1
return result
def polystr(a):
poly=[]
for i in range(len(a)):
if (a[i]=="1"):
poly.append("x^%d"%(len(a)-1-i))
return "+".join(poly)
def poly(a):
return polystr("{0:b}".format(a))
def repair(a,b): # "repair" two bit errors by brute force.
r=divide(a,b)
if(r==0):
return (0,b)
blen=len(b)
bnum=int(b,2)
for b1 in range(len(b)):
bnum1=bnum^(1<<b1)
bnum1str=("{0:0%db}"%blen).format(bnum1)
r=divide(a,bnum1str)
if(r==0):
return (1,bnum1str)
for b2 in range(b1+1,len(b)):
bnum2=bnum1^(1<<b2)
bnum2str=("{0:0%db}"%blen).format(bnum2)
r=divide(a,bnum2str)
if(r==0):
return (2,bnum2str)
return(-1,b)
def nrepair1(a,b): # "repair" one bit error by brute force.
r=ndivide(a,b)
if(r==0):
return (0,b)
blen=len(b)
bnum=int(b,2)
for b1 in range(len(b)):
bnum1=bnum^(1<<b1)
r=nndivide(a,bnum1)
if(r==0):
bnum1str=("{0:0%db}"%blen).format(bnum1)
return (1,bnum1str)
return(-1,b)
def nrepair(a,b): # "repair" two bit errors by brute force.
r=ndivide(a,b)
if(r==0):
return (0,b)
blen=len(b)
bnum=int(b,2)
for b1 in range(len(b)):
bnum1=bnum^(1<<b1)
r=nndivide(a,bnum1)
if(r==0):
bnum1str=("{0:0%db}"%blen).format(bnum1)
return (1,bnum1str)
for b1 in range(len(b)):
bnum1=bnum^(1<<b1)
for b2 in range(b1+1,len(b)):
bnum2=bnum1^(1<<b2)
r=nndivide(a,bnum2)
if(r==0):
bnum2str=("{0:0%db}"%blen).format(bnum2)
return (2,bnum2str)
return(-1,b)
def bch_repair1(poly,bits):
(errs,repaired)=nrepair1(poly,bits)
return (errs,repaired[:-poly.bit_length()+1],repaired[-poly.bit_length()+1:])
def bch_repair(poly,bits):
(errs,repaired)=nrepair(poly,bits)
return (errs,repaired[:-poly.bit_length()+1],repaired[-poly.bit_length()+1:])