www.pudn.com > ReedSolomon_codec.rar > ReedSolomon.cpp


// ReedSolomon.cpp: implementation of the CReedSolomon class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "ReedSolomon.h" 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
//预定义值,不要改变它 
_INIT_DATA Tab[] = { 
{2, 0x7, 1, 1, 1, 10 }, 
{3, 0xb, 1, 1, 2, 10 }, 
{4, 0x13, 1, 1, 4, 10 }, 
{5, 0x25, 1, 1, 6, 10 }, 
{6, 0x43, 1, 1, 8, 10 }, 
{7, 0x89, 1, 1, 10, 10 }, 
{8, 0x11d, 1, 1, 32, 10 }, 
{8, 0x187, 112,11, 32, 10 }, /* Duplicates CCSDS codec */ 
{9, 0x211, 1, 1, 32, 10 }, 
{10,0x409, 1, 1, 32, 10 }, 
{11,0x805, 1, 1, 32, 10 }, 
{12,0x1053, 1, 1, 32, 5 }, 
{13,0x201b, 1, 1, 32, 2 }, 
{14,0x4443, 1, 1, 32, 1 }, 
{15,0x8003, 1, 1, 32, 1 }, 
{16,0x1100b, 1, 1, 32, 1 }, 
{0, 0, 0, 0, 0}, 
}; 
/************************************************************************ 
类CReedSolomon用于RS码的解码及编码 
有两种方式初始化: 使用下面的_INIT_DATA或者使用预定义的值(只指定symsize). 
symsize表示2的多少次方, 码长为2**symsize. 
genpoly生成多项式, 应该为不可约多项式, 可参照预定义值 
fcs 应该小于(1 << symsize). 
prim 不能为0, 且小于(1 << symsize) 
nroots 应该小于(1 << symsize), 表示校验码的长度.  
纠错能力为0~nroots/2. 
************************************************************************/ 
 
// test.cpp:  
// 
////////////////////////////////////////////////////////////////////// 
#include "ReedSolomon.h" 
#include  
#include  
using namespace std; 
 
int main() 
{ 
// CReedSolomon < int > rs(3); 
CReedSolomon  rs(2, 0x7, 1, 1, 2); 
// CReedSolomon  rs(4, 0x13, 1, 1, 10); 
int trials = 5; 
int* block = new int[rs.m_nn]; 
int* tblock = new int[rs.m_nn]; 
int i; 
int errors; 
int* errlocs = new int[rs.m_nn]; 
int* derrlocs = new int[rs.m_nroots]; 
int derrors; 
int errval; 
int errloc; 
int erasures; 
int decoder_errors = 0; 
 
 
while (trials-- != 0) 
{ 
/* Test up to the error correction capacity of the code */ 
for (errors = 0; errors <= rs.m_nroots / 2; errors++) 
{ 
/* Load block with random data and encode */ 
for (i = 0; i < rs.m_nn - rs.m_nroots; i++) 
block[i] = rand() & rs.m_nn; 
 
printf("encode:\n"); 
for (i = 0; i < rs.m_nn - rs.m_nroots; i++)printf("%3d ", block[i]); 
printf("\n"); 
rs.Encode(&block[0], &block[rs.m_nn - rs.m_nroots]); 
for (i = 0; i < rs.m_nn; i++)printf("%3d ", block[i]); 
printf("\n"); 
/* Make temp copy, seed with errors */ 
memcpy(tblock, block, rs.m_nn * sizeof(block[0])); 
memset(errlocs, 0, rs.m_nn * sizeof(errlocs[0])); 
memset(derrlocs, 0, rs.m_nroots * sizeof(derrlocs[0])); 
 
erasures = 0; 
for (i = 0; i < errors; i++) 
{ 
do 
{ 
errval = rand() & rs.m_nn; 
} while (errval == 0); 
 
/* Error value must be nonzero */ 
 
do 
{ 
errloc = rand() % rs.m_nn; 
} while (errlocs[errloc] != 0); 
 
/* Must not choose the same location twice */ 
 
errlocs[errloc] = 1; 
 
#if FLAG_ERASURE 
if (rand() & 1) /* 50-50 chance */ 
derrlocs[erasures++] = errloc; 
#endif 
tblock[errloc] ^= errval; 
} 
 
/* Decode the errored block */ 
 
printf("decode:\n"); 
for (i = 0; i < rs.m_nn; i++)printf("%3d ", tblock[i]); 
printf("\n"); 
derrors = rs.Decode(tblock, derrlocs, erasures); 
for (i = 0; i < rs.m_nn; i++)printf("%3d ", tblock[i]); 
printf("\n%d errors\n", derrors); 
 
if (derrors != errors) 
{ 
printf(" decoder says %d errors, true number is %d\n", derrors, 
errors); 
decoder_errors++; 
} 
 
for (i = 0; i < derrors; i++) 
{ 
if (errlocs[derrlocs[i]] == 0) 
{ 
printf(" decoder indicates error in location %d without error\n", 
i); 
decoder_errors++; 
} 
} 
 
if (memcmp(tblock, block, sizeof(tblock[0]) * rs.m_nn) != 0) 
{ 
printf(" uncorrected errors! output ^ input:"); 
decoder_errors++; 
for (i = 0; i < rs.m_nn; i++) 
printf(" %02x", tblock[i] ^ block[i]); 
printf("\n"); 
} 
printf("\n"); 
} 
} 
 
delete block; 
delete tblock; 
delete errlocs; 
delete derrlocs; 
if (decoder_errors == 0) printf("OK\n"); 
return decoder_errors; 
return 0; 
}