---
# System prepended metadata

title: ECC Error-Correcting Code
tags: [漢明碼, C語言]

---

# ECC Error-Correcting Code 
*Author:Wei-Li NKUST CSIE CVLAB*
###### tags: `漢明碼` `C語言`

## Algorithm
![](https://i.imgur.com/9SrEuJk.png)

### 編碼過程

從左到右數
輸入一個8bit ==1001 1010==

會變成 ==0111 0010 1010==

轉換過程如下 p1的六個位置的數 1的總和要是偶數  p2 p4 p8以此類推
![](https://i.imgur.com/bkvBdYm.png)

### 檢查是否有錯

==故意在第10位元把0改成1==
![](https://i.imgur.com/wTP6ZWH.png)

**驗證過程**
![](https://i.imgur.com/oG3qcVY.png)
回推 可以知道 第10位元是錯的

==**~~若錯兩位元 那回推之後 會超過12位元~~**==
認知有誤 待修正中
**目前已知 漢名碼在兩個錯誤的時候可能會有問題**

:::info
第一個副程式

當我們丟入8Bit原始資料，請幫我們產出校正碼
並回傳出來校正碼+原始資料
:::


```c=
int *Encode(int data[8]){
	static int outputdata[12]={0,0,0,0,0,0,0,0,0,0,0,0};
	outputdata[2]=data[0];
	outputdata[4]=data[1];
	outputdata[5]=data[2];
	outputdata[6]=data[3];
	outputdata[8]=data[4];
	outputdata[9]=data[5];
	outputdata[10]=data[6];
	outputdata[11]=data[7];
    
	//Calculation of even parity   XOR
	outputdata[0]=outputdata[2]^outputdata[4]^outputdata[6]^outputdata[8]^outputdata[10];
	outputdata[1]=outputdata[2]^outputdata[5]^outputdata[6]^outputdata[9]^outputdata[10];
	outputdata[3]=outputdata[4]^outputdata[5]^outputdata[6]^outputdata[11];
 	outputdata[7]=outputdata[8]^outputdata[9]^outputdata[10]^outputdata[11];
	return outputdata;
}
```
**採用陣列進 陣列出**
結構是一維陣列 輸入長度為8 
==EX: int mydata[8]={1,0,0,1,1,0,1,0};==


:::info
第二個副程式 **(有BUG 2020/06/09)**

當輸入校正碼+8bit原始資料，其中有1碼錯誤時，請用ECC將錯誤碼修正回來
並回兩筆變數資料

第一筆為:修正後資料
第二筆: 無法修復的變數設定為0，並回傳

那萬一有兩碼錯時，ECC無法修復，則無法修復的變數設定為1，並回傳
:::

```c=
struct fixdata{
	int *data;
	int fix;
};

fixdata ecc(int datacheck[12]){
	int p,p0,p1,p3,p7;
	fixdata fd;
	p0=datacheck[0]^datacheck[2]^datacheck[4]^datacheck[6]^datacheck[8]^datacheck[10];
	p1=datacheck[1]^datacheck[2]^datacheck[5]^datacheck[6]^datacheck[9]^datacheck[10];
	p3=datacheck[3]^datacheck[4]^datacheck[5]^datacheck[6]^datacheck[11];
	p7=datacheck[7]^datacheck[8]^datacheck[9]^datacheck[10]^datacheck[11];
	//printf("p7: %d p3: %d p1: %d p0: %d \n",p7,p3,p1,p0);
	p=p7*8+p3*4+p1*2+p0;
	
	if(p==0){
		fd.data=datacheck;
		fd.fix=0;
		printf("\nno error !\n\n");
	}
	else if(p>12){
		//error  bug
		printf("\n have two error cannot fix ! \n");
		fd.fix=1;
	}
	else{
		printf("\n錯誤的位元是第 %d 位元 \n",p);
		if(datacheck[p-1]==0){
			datacheck[p-1]=1;
		}else{
			datacheck[p-1]=0;
		}
		fd.data=datacheck;
		fd.fix=0;
	}
	return fd;
}

```
*做了一個結構可以回傳兩個值*
*第一個為修正後*
*第二個是可不可以修正*
**同樣是陣列輸入**
結構是一維陣列 輸入長度為12 
==EX: int datacheck[12]={1,1,1,1,0,0,1,0,1,0,1,0};==



## 總覽
```c=
//coding by wei 2020-5-11
//it can work on windows10 x64 dev-c++ or visual studio2017

#include<stdio.h>
#include<iostream>

//第一個副程式
//傳陣列進來這個   
// 8bit 幫你轉成 12bit (8+4)  4是校證碼(_)   _ _ X _ X X X _ X X X X  
int *Encode(int data[8]){
	static int outputdata[12]={0,0,0,0,0,0,0,0,0,0,0,0};
	outputdata[2]=data[0];
	outputdata[4]=data[1];
	outputdata[5]=data[2];
	outputdata[6]=data[3];
	outputdata[8]=data[4];
	outputdata[9]=data[5];
	outputdata[10]=data[6];
	outputdata[11]=data[7];
		
	//Calculation of even parity   XOR
	outputdata[0]=outputdata[2]^outputdata[4]^outputdata[6]^outputdata[8]^outputdata[10];
	outputdata[1]=outputdata[2]^outputdata[5]^outputdata[6]^outputdata[9]^outputdata[10];
	outputdata[3]=outputdata[4]^outputdata[5]^outputdata[6]^outputdata[11];
 	outputdata[7]=outputdata[8]^outputdata[9]^outputdata[10]^outputdata[11];
	return outputdata;
}
//自創結構 
struct fixdata{
	int *data;
	int fix;
};

fixdata ecc(int datacheck[12]){
	int p,p0,p1,p3,p7;
	fixdata fd;
	p0=datacheck[0]^datacheck[2]^datacheck[4]^datacheck[6]^datacheck[8]^datacheck[10];
	p1=datacheck[1]^datacheck[2]^datacheck[5]^datacheck[6]^datacheck[9]^datacheck[10];
	p3=datacheck[3]^datacheck[4]^datacheck[5]^datacheck[6]^datacheck[11];
	p7=datacheck[7]^datacheck[8]^datacheck[9]^datacheck[10]^datacheck[11];
	//printf("p7: %d p3: %d p1: %d p0: %d \n",p7,p3,p1,p0);
	p=p7*8+p3*4+p1*2+p0;
	
	if(p==0){
		fd.data=datacheck;
		fd.fix=0;
		printf("\nno error !\n\n");
	}
	else if(p>12){
		//error  bug
		printf("\n have two error cannot fix ! \n");
		fd.fix=1;
	}
	else{
		printf("\n錯誤的位元是第 %d 位元 \n",p);
		if(datacheck[p-1]==0){
			datacheck[p-1]=1;
		}else{
			datacheck[p-1]=0;
		}
		fd.data=datacheck;
		fd.fix=0;
	}
	return fd;
}

int main(){
	
	int inputdata[8]={1,0,0,1,1,0,1,0}; //輸入 
	int *data;
	
	data=Encode(inputdata);
	
	for (int i=0;i<12;i++) {
		printf("%d",data[i]);
	}
	
	printf("\n\n");

	printf("輸入校正碼(4bit)+原始資料(8bit) 12bit \n");
	//011100101010
	int datacheck[12]={0,1,1,1,0,0,1,0,1,0,1,0}; //輸入驗證 
	
	for (int i=0;i<12;i++) {
		printf("%d",datacheck[i]);
	}
	
	printf("\n\n");
	
	fixdata fd; //宣告自創結構 
	
	fd=ecc(datacheck);
	
	for (int i=0;i<12;i++) {
		printf("%d",fd.data[i]);
	}
	
	printf("\n\nfix : %d",fd.fix);
	printf("\n\n\n");
	system("pause");
 	return 0;
}

```

::: spoiler  補充
SEC-DED = Single-Error-Correcting and Double-Error-Detecting code
:::


>reference
> [The Hamming Single Error Correction Code (ECC) - 朱宗賢老師](https://www.youtube.com/watch?v=fgHaBP9s7t4&fbclid=IwAR2z-g_GYb975EluYpzxf-RJAfzoxwlXjXngVTJAbn9Ks7M1jstsMjK9PGM)
> [漢明碼](https://zh.wikipedia.org/wiki/%E6%B1%89%E6%98%8E%E7%A0%81)