UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:python_reedsolomon

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 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]
code/python_reedsolomon.txt ยท Last modified: 2008/07/19 23:33 (external edit)