例如输入的数据为(a3~a6) 0001
根据监督位计算结果的表单得到a0 a1 a2的值为011
计算得到数据0001011。
若对方收到的数据为0101011。
分解得到(a3~a6)0101,(a0~02)011。
根据监督位计算结果的表单得值与011不相等得知有错误。
S1=1 S2=1 S3=0, 得到错误码是A5,所以正确的数据应该为000111
若对方收到的数据为1101011。
分解得到(a3~a6)1101,(a0~02)011。
根据监督位计算结果的表单得值与011不相等得知有错误。
S1=0 S2=0 S3=1, 得到错误码是A1,所以正确的数据应该为1101010,解包错误
若对方收到的数据为1101010。
分解得到(a3~a6)1101,(a0~02)010。
根据监督位计算结果的表单得值与011不相等得无错误。
说明:
S1 S2 S3用来计算错误码的位置。
a1 a2 a3用来校验是否错误。
数据组成 a6 a5 a4 a3 a2 a1 a0 构成一个数据段,
相关公式
a2 = a6⊕a5⊕a4
a1 = a6⊕a5⊕a3
a0 = a6⊕a4⊕a3
S1 = a6⊕a5⊕a4⊕a2 (1)式
S2 = a6⊕a5⊕a3⊕a1 (2)式
S3 = a6⊕a4⊕a3⊕a0 (3)式
相关表单
S1 S2 S3 错码的位置
0 0 1 a0
0 1 0 a1
1 0 0 a2
0 1 1 a3
1 0 1 a4
1 1 0 a5
1 1 1 a6
0 0 0 无错
监督位计算结果
序 号 | 码 字 | 序 号 | 码 字 | ||
信 息码元(输入数据) | 监 督 元(A0~A2) | 信 息码元(输入数据) | 监 督 元(A0~A2) | ||
0 | 0 0 0 0 | 0 0 0 | 8 | 1 0 0 0 | 1 1 1 |
1 | 0 0 0 1 | 0 1 1 | 9 | 1 0 0 1 | 1 0 0 |
2 | 0 0 1 0 | 1 0 1 | 10 | 1 0 1 0 | 0 1 0 |
3 | 0 0 1 1 | 1 1 0 | 11 | 1 0 1 1 | 0 0 1 |
4 | 0 1 0 0 | 1 1 0 | 12 | 1 1 0 0 | 0 0 1 |
5 | 0 1 0 1 | 1 0 1 | 13 | 1 1 0 1 | 0 1 0 |
6 | 0 1 1 0 | 0 1 1 | 14 | 1 1 1 0 | 1 0 0 |
7 | 0 1 1 1 | 0 0 0 | 15 | 1 1 1 1 | 1 1 1 |
结论:
在速率慢或者简单误码的地方可以使用,若误码率高的地方反而会引起不良。并且只能纠正一个错误码。
#include "fec.h"
fec::fec()
{
}
void fec::Code(unsigned char *pIn, unsigned int InSLen, unsigned char *pOut, unsigned int *OutSLen){
unsigned char CodeTable[16] = {0x0, 0x3, 0x5, 0x6,
0x06, 0x5, 0x3, 0x0,
0x7, 0x4, 0x2, 0x1,
0x1, 0x2, 0x4, 0x7};
/* 进行比特位操作 */
unsigned char H = 0;
unsigned char L = 0;
unsigned char OutCur = 7;
unsigned int Ops = 0;
pOut[Ops] = 0xAA;
for(int i=0; i<InSLen; i++){
H = (pIn[i]>>4)&0x0F;
L = pIn[i]&0x0F;
H = ((CodeTable[H]^0x04)&0x07) + (H<<3);
L = ((CodeTable[L]^0x04)&0x07) + (L<<3);
/* 进行位压缩 */
for(int j=0; j<7; j++){
if(H&(0x40>>j)){ /* 为1 */
pOut[Ops] |= (0x01)<<OutCur;
}else{
pOut[Ops] &= ~((0x01)<<OutCur);
}
if(OutCur==0){
OutCur = 7;
Ops ++;
pOut[Ops] = 0xAA;
}else{
OutCur --;
}
}
for(int j=0; j<7; j++){
if(L&(0x40>>j)){ /* 为1 */
pOut[Ops] |= (0x01)<<OutCur;
}else{
pOut[Ops] &= ~((0x01)<<OutCur);
}
if(OutCur==0){
OutCur = 7;
Ops ++;
pOut[Ops] = 0xAA;
}else{
OutCur --;
}
}
}
if(OutCur!=7){
Ops ++;
}
*OutSLen = Ops;
}
void fec::Decode(unsigned char *pIn, unsigned int InSLen, unsigned char *pOut,unsigned int *OutSLen){
unsigned char CodeTable[16] = {0x0, 0x3, 0x5, 0x6,
0x06, 0x5, 0x3, 0x0,
0x7, 0x4, 0x2, 0x1,
0x1, 0x2, 0x4, 0x7};
unsigned char ErrorTable[7] = {0,1,3,2,4,5,6};
/* 进行比特位操作 */
unsigned char HByte = 0;
unsigned char LByte = 0;
unsigned char HCode = 0;
unsigned char LCode = 0;
unsigned char OutCur = 0;
unsigned int Ops = 0;
unsigned int All = 0;
unsigned char s1 = 0, s2 = 0, s3 = 0;
unsigned char s = 0;
unsigned char Wid = 0;
InSLen = InSLen * 8 / 14;
for (int i=0; i<InSLen; i++) {
/* 解除高字节编码 */
HByte = 0;
LByte = 0;
for(int j=0; j<7; j++){
if(pIn[Ops]&(0x80>>OutCur)){
HByte |= ((0x40)>>j);
}
if(OutCur>=7){
OutCur = 0;
Ops ++;
}else{
OutCur ++;
}
}
for(int j=0; j<7; j++){
if(pIn[Ops]&(0x80>>OutCur)){
LByte |= (0x40)>>j;
}
if(OutCur>=7){
OutCur = 0;
Ops ++;
}else{
OutCur ++;
}
}
HCode = (HByte^0x04) & 0x07;
LCode = (LByte^0x04) & 0x07;
HByte = (HByte >> 3)&0x0F;
LByte = (LByte >> 3)&0x0F;
if(CodeTable[HByte]!=HCode){
/* 进行补偿 */
s1 = (((HByte&0x08)>>3) + ((HByte&0x04)>>2) + ((HByte&0x02)>>1) + ((HCode&0x04)>>2))&0x01 ;
s2 = (((HByte&0x08)>>3) + ((HByte&0x04)>>2) + (HByte&0x01) + ((HCode&0x02)>>1))&0x01 ;
s3 = (((HByte&0x08)>>3) + ((HByte&0x02)>>1) + (HByte&0x01) + (HCode&0x01))&0x01 ;
s = (s1<<2)+(s2<<1)+s3;
if(s>0){
Wid = ErrorTable[s-1];
if(Wid>=3){
Wid -= 3;
if(HByte&(0x01<<Wid)){
HByte &= ~(0x01<<Wid);
}else{
HByte |= (0x01<<Wid);
}
}
}
}
if(CodeTable[LByte]!=LCode){
/* 进行补偿 */
s1 = (((LByte&0x08)>>3) + ((LByte&0x04)>>2) + ((LByte&0x02)>>1) + ((LCode&0x04)>>2))&0x01 ;
s2 = (((LByte&0x08)>>3) + ((LByte&0x04)>>2) + (LByte&0x01) + ((LCode&0x02)>>1))&0x01 ;
s3 = (((LByte&0x08)>>3) + ((LByte&0x02)>>1) + (LByte&0x01) + (LCode&0x01))&0x01 ;
s = (s1<<2)+(s2<<1)+s3;
if(s>0){
Wid = ErrorTable[s-1];
if(Wid>=3){
Wid -= 3;
if(LByte&(0x01<<Wid)){
LByte &= ~(0x01<<Wid);
}else{
LByte |= (0x01<<Wid);
}
}
}
}
pOut[All] = ((HByte<<4)+LByte)&0xFF;
All ++;
}
*OutSLen = All;
}