===== Main code (uses a c library for decoding, as the tx only has to encode, and we're assuming running binaries on the ground is easy) ===== The decoder can be found at [[http://hathawaymix.org/Software/ReedSolomon|hathawaymix.org]] #!/usr/bin/python mm=7 # RS code over GF(2**4) - change to suit tt=16 # number of errors that can be corrected nn=2**mm -1 #length of codeword kk = nn-2*tt primative_polynomials=[[1,1,0,1],[1,1,0,0,1],[1,0,1,0,0,1],[1,1,0,0,0,0,1],[1,0,0,1,0,0,0,1],[1,0,1,1,1,0,0,0,1],[1,0,0,0,1,0,0,0,0,1]] pp=primative_polynomials[mm-3] # specify irreducible polynomial coeffts m=5 alpha_to=[0]*(nn+1) index_of=[0]*(nn+1) gg=[0]*(nn-kk+1) recd=[0]*(nn) data=[0]*(kk) bb=[0]*(nn-kk) def generate_gf(): # generate GF(2**mm) from the irreducible polynomial p(X) in pp[0]..pp[mm] # lookup tables: index->polynomial form alpha_to[] contains j=alpha**i; # polynomial form -> index form index_of[j=alpha**i] = i # alpha=2 is the primitive element of GF(2**mm) mask = 1 alpha_to[mm] = 0 for i in range(mm): alpha_to[i] = mask index_of[alpha_to[i]] = i if pp[i]!=0: alpha_to[mm] ^= mask mask <<= 1 index_of[alpha_to[mm]] = mm mask >>= 1 for i in range(mm+1,nn): if (alpha_to[i-1] >= mask): alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) else: alpha_to[i] = alpha_to[i-1]<<1 index_of[alpha_to[i]] = i index_of[0] = -1 ; def gen_poly(): # Obtain the generator polynomial of the tt-error correcting, length # nn=(2**mm -1) Reed Solomon code from the product of (X+alpha**i), i=1..2*tt gg[0] = 2 # primitive element alpha = 2 for GF(2**mm) gg[1] = 1 # g(x) = (X+alpha) initially for i in range(2,nn-kk+1): gg[i] = 1 for j in range(i-1,0,-1): if (gg[j] != 0): gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]]+i)%nn] else: gg[j] = gg[j-1] gg[0] = alpha_to[(index_of[gg[0]]+i)%nn] ; # gg[0] can never be zero # convert gg[] to index form for quicker encoding */ for i in range(0,nn-kk): gg[i] = index_of[gg[i]] ; def encode_rs(): # take the string of symbols in data[i], i=0..(k-1) and encode systematically # to produce 2*tt parity symbols in bb[0]..bb[2*tt-1] # data[] is input and bb[] is output in polynomial form. # Encoding is done by using a feedback shift register with appropriate # connections specified by the elements of gg[], which was generated above. # Codeword is c(X) = data(X)*X**(nn-kk)+ b(X) for i in range(0,nn-kk): bb[i] = 0 for i in range(kk-1,-1,-1): feedback = index_of[data[i]^bb[nn-kk-1]] if feedback != -1: for j in range(nn-kk-1,0,-1): if gg[j] !=-1: bb[j] = bb[j-1]^alpha_to[(gg[j]+feedback)%nn] else: bb[j] = bb[j-1] bb[0] = alpha_to[(gg[0]+feedback)%nn] else: for j in range(nn-kk-1,0,-1): bb[j] = bb[j-1] bb[0] = 0 def setup_rs(): # generate the Galois Field GF(2**mm) generate_gf() #compute the generator polynomial for this RS code gen_poly() def encode_string(s): d=0 for i in s: data[d]=ord(i) d=d+1 for i in range(len(s),kk): data[i]=0 # encode data[] to produce parity in bb[]. Data input and parity output # is in polynomial form encode_rs() # put the transmitted codeword, made up of data plus parity, in recd[] */ for i in range(0,nn-kk): recd[i] = bb[i] for i in range(0,kk): recd[i+nn-kk] = data[i] # print recd # print len(recd) s='' for i in range(2*tt,len(recd)): #pick all the human readable data s+=chr(recd[i]) for i in range(2*tt): s+=chr(recd[i]) # print s return s def decode_string(s,corruption): #corruption is a list of know corrupted chr positions from reedsolomon import Codec c=Codec(nn,kk,mm) f='' for i in range(2*tt): #pick all the parity and put @ front f+=s[len(s)+i-2*tt] for i in range(2*tt,len(s)): #copy over the data f+=s[i-2*tt] t='' for i in range(len(f)): #reverses the whole string t+=f[len(f)-len(t)-1] #print len(t) #print t t=c.decode(t,corruption) del s s='' b='' for i in t[0]: b+=t[0][len(t[0])-len(b)-1] for i in range(len(b)): s+=b[i] return s,t[1] ===== Usage example ===== import reed_solomon reed_solomon.setup_rs() s=reed_solomon.encode_string("hello world my name is Laurence and I am your supreme ruler !!!111!!111!") print s t=s[0:9]+"df"+s[11:len(s)] d = reed_solomon.decode_string(t,[]) print d[0] print "Errors at: ",d[1] ===== produces: ===== $ python testcode.py hello world my name is Laurence and I am your supreme ruler !!!111!!111! dJ{,wOWOIUv?M ]'tkN{edkM98 hello world my name is Laurence and I am your supreme ruler !!!111!!111! Errors at: [84, 85]