文章目录

  最近学通信网的时候,方老师给我们布置了两个作业,分别是hamming编码译码和CRC校验模拟。Hamming编译码以前写过一个hamming(7,4)的模拟器,所以直接copy了以前的。额外写了个CRC校验的,由于太懒,所以直接CRC4,其实原理都差不多。

  最核心的就是如何实现模二除法运算,关于这部分参考了这篇文章的思路:课程设计报告–用模2除法计算CRC码的CRC校验软件设计(http://www.docin.com/p-716983519.html

  摘录其中核心部分如下:

I. 题目:

  以ppt中的例题为例

  信息多项式为:x7+x5+1,生成多项式为:x3+1,问:实际传输的比特串为什么?

  解答:x7+x5+1=10100001;x3+1=1001

  余数为:x2+x+1=111

  实际传输的比特串为:10100001111

II. 主程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package crc;
import java.util.Arrays;
/**
* CRC编译码模拟试验
* 以ppt中的CRC4为例,其余的CRC8或CRC16之类的基本类似,稍作改动即可
* @author jrhu05
*
*/
public class CRC4 {
public static void main(String[] args) {
int[] information={1,0,1,0,0,0,0,1};
int[] genarete={1,0,0,1};
System.out.println("待编译的二进制序列是:"+Arrays.toString(information));
System.out.println("生成多项式是:"+Arrays.toString(genarete));
System.out.println("————进行编译操作————");
int[] encode=crcEncode(genarete,information);
System.out.println("编译好的二进制序列是:");
System.out.println(Arrays.toString(encode));
System.out.println("————下面进行CRC4的校验测试————");
System.out.println("假设传过来的序列发生了一位错误,错误后的编码是:");
int[] wrong=randomWrong(encode);
System.out.println(Arrays.toString(wrong));
System.out.println("根据生成多项式1001来进行检查");
int[] remainCheck=mod2Div(wrong, genarete);
boolean isRight=notContainZero(remainCheck);
if (isRight) {
System.out.println("由于检测余数 "+Arrays.toString(remainCheck)+"是全0的,故该序列是没有错误的");
}else {
System.out.println("由于检测余数 "+Arrays.toString(remainCheck)+"不是全0的,故该序列是发生错误的");
}
}
/**
* 检测一二进制序列是否完全为0
* @param remainCheck 待检测序列
* @return 是否全为0
*/
private static boolean notContainZero(int[] remainCheck) {
// TODO 自动生成的方法存根
for (int i = 0; i < remainCheck.length; i++) {
if (remainCheck[i]==1) {
return false;
}
}
return true;
}
/**
* 编码
* @param genarete 生成多项式
* @param information 信息多形式
* @return 编码后的二进制序列
*/
private static int[] crcEncode(int[] genarete,int[] information) {
// TODO 自动生成的方法存根
//将信息码抬高n位,n为生成多项式的最高项次数
int up=genarete.length-1;
int[] newInfo=new int[information.length+up];
for (int i = 0; i < information.length; i++) {
newInfo[i]=information[i];
}
for (int i = information.length; i < newInfo.length; i++) {
newInfo[i]=0;
}
//进行模二除法
int[] remain=mod2Div(newInfo,genarete);
//进行余数和源信息的拼接生成最后的编码
int starIndex=information.length;
for (int i = 0; i < remain.length; i++) {
newInfo[starIndex+i]=remain[i];
}
return newInfo;
}

/**
* 模二除法求余数
* @param newInfo 被除数
* @param newGen 除数
* @return 余数
*/
private static int[] mod2Div(int[] newInfo, int[] genarete) {
//将生成多项式的最高位去掉,因为最高位经过xor肯定出0所以不用考虑
int[] newGen=new int[genarete.length-1];
for (int i = 0; i < newGen.length; i++) {
newGen[i]=genarete[i+1];
}
// TODO 自动生成的方法存根
int flag=newInfo[0];
//余数存储矩阵初始化
int[] temp=new int[newGen.length];
int lastIndex=temp.length-1;
for (int i = 0; i < temp.length; i++) {
temp[i]=newInfo[i+1];
}
//初始化计数器
int count=temp.length+1;
//进行窗口推进式xor运算
while (count<=newInfo.length) {
if (flag==1) {
temp=xorGroup(temp, newGen);
}
//标记位为temp的高位,如果为1则表示下一次运算结果可也上1,否则只能上0
if (count<newInfo.length) {
flag=temp[0];
//temp运算窗口移动一位,同时计数器自加
for (int i = 0; i <temp.length-1; i++) {
temp[i]=temp[i+1];
}
temp[lastIndex]=newInfo[count];
}
count++;

}
System.out.println("模二运算计算出的余数:");
System.out.println(Arrays.toString(temp));
return temp;
}
/**
* 对两个二进制序列进行异或运算
* @param a 待计算序列1
* @param b 待计算序列2
* @return 异或运算结果
*/
private static int[] xorGroup(int[] a,int[] b){
int[] result=new int[a.length];
for (int i = 0; i < a.length; i++) {
result[i]=xor(a[i],b[i]);
}
return result;
}
/**
* 对两个二进制位进行异或运算
* @param i 待计算二进制位1
* @param j 待计算二进制位2
* @return 异或运算结果
*/
private static int xor(int i, int j) {
// TODO 自动生成的方法存根
if (i==j) {
return 0;
}else {
return 1;
}
}

/**
* 随机生成一位错误
* @param encode 待错比特串
* @return 有一位错误的比特串
*/
private static int[] randomWrong(int[] encode) {
// TODO 自动生成的方法存根

int wrongIndex=(int) (Math.random()*encode.length);
int[] wrong=encode;
//对错误位进行取反
if (wrong[wrongIndex]==0) {
wrong[wrongIndex]=1;
}else {
wrong[wrongIndex]=0;
}
return wrong;
}
}

III. 实验结果截图:


如果觉得文章很有趣或对你带来了帮助,欢迎请我喝杯咖啡哦~

文章目录