縮短迴圈碼BCH(26,16)編解碼原理與二進位制演算法
1.BCH(26,16)的基本簡介
BCH(26,16)是一種縮短迴圈校驗碼,它的資料位為16位,校驗位是10位,碼字的長度為26位。BCH(26,16)碼取(31,21)迴圈碼中的前5位資訊位為0的碼字作為碼字,構成(21-5)維的線性子空間,它最多能夠糾正t=2位錯誤(,其中m是GF(p^m)中的m,這裡的m=5,n=31,k=21)。對於鐵路在800M頻段上的資料業務,它採用的生成多項式為G(X)=X^10+X^8+X^7+X^5+X^4+X^3+1。
2.BCH(26,16)的編碼原理
我們假設C(X)是需要傳送的數字,,在這裡C15C14....C1C0你是我們需要傳送的二進位制資料。假設R(X)是校驗位,
unsigned int CX = 0x5555,RX;//16位的資料位 CX = CX<<10;//相當於C(X)X10 unsigned int gx = 0x05B9<<(26-11); for(int i=0;i<16;i++){//迭代迴圈16次,進行16次除法操作,最後剩下10位的餘數 if((CX&0x2000000)!=0){//對CX的最高位是否為1,如果是1,做減法操作(異或) CX ^=gx ;//擴充套件gx到與CX同樣是26位,為了方便除法運算 } CX = CX<<1; } RX = CX>>16; printf("CX為校驗位是 %2x",RX);
3. BCH(26,16)的解碼原理
3.1用BCH的生成多項式校驗資料是否正確,即使用接收到的26位碼M(X)= C(X)X^10+R(X)除以生成多項式G(X)。如果餘數為0,那麼校驗正確,否則校驗錯誤,需要糾錯。
unsigned int code = 0; unsigned int gx = 0x05B9<<(26-11); code = 0x3fffccd; unsigned int res = 0; for(int i=0;i<16;i++){//求餘數的演算法中,只需要除以最高位的16位,餘數一定是10位。 if((code&0x2000000)!=0){ code ^=gx; } code = code <<1; } Res = code>>(26-10); printf("餘數 %2x\n",res);
3.2如果只錯了1位或者2位。假設傳送方傳送的碼為,由於只錯了一位,那麼假設錯的這位是Cx,則接收到的碼為。我們的問題是如何知道錯誤的位置x,以及所對應的Cx?上面的關係實際上表明R(X)=C(X)+E(X),其中。我們已經知道R(X),生成多項式G(X)和R(X)%G(X)的餘數r(X),現在需要求出C(X)。,如果我們前期計算了一個表,這個表中表明唯一的一個E(X)對應唯一的一個r(X),唯一的r(x)不一定代表唯一的E(X),但是我們假設了只存在一個錯誤,那麼通過查表我們就可以知道E(X)。當求解出E(X)後,C(X)=R(X)-E(X)=R(X)+E(X),這樣R(X)和E(X)進行異或運算就可以得到C(X)。這種方式能夠解決一位出錯的情況,但是當2位出錯的時候,可以改寫表示式為,因此只要檢測到錯誤的這兩位,然後把它修正了就可以了。具體的解碼程式如下。
unsigned int CheckMatrix[26][2];
#define gx 0x05B9<<(26-11)
//create check metric
void CreateCheckMatrix(){
unsigned int RX,CX;
CX = 1<<15;
for(int i=0;i<16;i++){
if(i<16){
RX = GetFEC(CX);
CheckMatrix[i][0] = RX;
CheckMatrix[i][1] = CX<<10;
}
CX = CX>>1;
}
CX = 1<<9;
for(int i=0;i<10;i++){
CheckMatrix[i+16][0] = CX;
CheckMatrix[i+16][1] = CX;
printf("%2x 為校驗位是 %2x\n",CX,CX);
CX = CX>>1;
}
}
//correct data error
unsigned int CorrectError(unsigned int code,unsigned int *value){
unsigned int encode = 0;
unsigned int decode = 0;
unsigned int res;
decode = code;
printf("decode %2x\n",code);
//2.1 calculate remainder
for(int i=0;i<16;i++){//求餘數的演算法中,只需要除以最高位的16位,餘數一定是10位。
if((code&0x2000000)!=0){
code ^=gx;
}
code = code <<1;
}
res = code>>(26-10);
printf("餘數 %2x\n",res);
if(res == 0){
*value = decode;
return 0;
}
//2.2 correct one bit error
for(int i=0;i<26;i++){
if(res == CheckMatrix[i][0]){
decode = decode^CheckMatrix[i][1];
*value = decode;
return 1;
}
}
//2.3 correct two bit error
for(int i=0;i<26;i++){
for(int j=i+1;j<26;j++){
if(res == (CheckMatrix[i][0]^CheckMatrix[j][0])){
decode = decode^CheckMatrix[i][1]^CheckMatrix[j][1];
*value = decode;
return 2;
}
}
}
return 3;
}
3.3最後BCH(26,16)編碼和解碼源程式如下
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
unsigned int CheckMatrix[26][2];
#define gx 0x05B9<<(26-11)
//get correct remainder
unsigned int GetFEC(unsigned int CX){
unsigned int RX;//16位的資料位
unsigned int tmp;
CX = CX<<10;
tmp = CX;
for(int i=0;i<16;i++){//迭代迴圈16次,進行16次除法操作,最後剩下10位的餘數
if((CX&0x2000000)!=0){//對CX的最高位是否為1,如果是1,做減法操作(異或)
CX ^=gx ;//擴充套件gx到與CX同樣是26位,為了方便除法運算
}
CX = CX<<1;
}
RX = CX>>16;
printf("%2x 為校驗位是 %2x\n",tmp,RX);
return RX;
}
//create check metric
void CreateCheckMatrix(){
unsigned int RX,CX;
CX = 1<<15;
for(int i=0;i<16;i++){
if(i<16){
RX = GetFEC(CX);
CheckMatrix[i][0] = RX;
CheckMatrix[i][1] = CX<<10;
}
CX = CX>>1;
}
CX = 1<<9;
for(int i=0;i<10;i++){
CheckMatrix[i+16][0] = CX;
CheckMatrix[i+16][1] = CX;
printf("%2x 為校驗位是 %2x\n",CX,CX);
CX = CX>>1;
}
}
//correct data error
unsigned int CorrectError(unsigned int code,unsigned int *value){
unsigned int encode = 0;
unsigned int decode = 0;
unsigned int res;
decode = code;
printf("decode %2x\n",code);
//2.1 calculate remainder
for(int i=0;i<16;i++){//求餘數的演算法中,只需要除以最高位的16位,餘數一定是10位。
if((code&0x2000000)!=0){
code ^=gx;
}
code = code <<1;
}
res = code>>(26-10);
printf("餘數 %2x\n",res);
if(res == 0){
*value = decode;
return 0;
}
//2.2 correct one bit error
for(int i=0;i<26;i++){
if(res == CheckMatrix[i][0]){
decode = decode^CheckMatrix[i][1];
*value = decode;
return 1;
}
}
//2.3 correct two bit error
for(int i=0;i<26;i++){
for(int j=i+1;j<26;j++){
if(res == (CheckMatrix[i][0]^CheckMatrix[j][0])){
decode = decode^CheckMatrix[i][1]^CheckMatrix[j][1];
*value = decode;
return 2;
}
}
}
return 3;
}
int main(int argc, char** argv) {
unsigned int code = 0,RX,CX;
unsigned int encode = 0,decode;
unsigned int res = 0;
unsigned int pos1=0,pos2=0,pos3=0;
//produce check metric
CreateCheckMatrix();
//encode
res = 0xffff;
encode = (res<<10)^GetFEC(res);
printf("encode %2x\n",encode);
//decode
// pos1 = 0x8;
pos2 = 0x2000000;
pos3 = 0x800000;
code = encode^pos1^pos2^pos3;
res = CorrectError(code,&decode);
printf("result %2x decode %2x\n",res,decode);
return 0;
}