杭州电子科技大学实验报告学生姓名:韩民杨实验地点: 1#108学号: 12081420 指导教师:吴端坡实验时间: 2015-4-24一、实验室名称: 1#108二、实验项目名称:计算机网络实验1Coding on error dectecting algorithms(C++)三、实验学时:四、实验原理: C++编程五、实验目的:利用 C++编程 CRC16校验及奇偶校验六、实验内容:Coding on error dectecting algorithms(C++)1.Cyclic redundancy checkUsing the polynomials below to encode random generated datastream (40-100bits). Show the FEC, and encoded data frame.CRC-4x4+x+1ITU G.704CRC-16x16+x15+x2+1IBM SDLCCRC-32x32+x26+x23+...+x2+ ZIP, RAR, IEEE 802 LAN/FDDI, IEEE x+11394, PPP-FCSFor the error patter listed below, what the conclusion does the receiver get? Can the receiver find the errors?Case Error patternNo error0000⋯⋯ 0000One error1000⋯ ..000Two errors100⋯ .001Random errors Random error pattern2.Parity checkUsing even or odd parity check on random generated data stream (8-20bits).Show encoded data frame.For the error patter listed below, what the conclusion does the receiver get?Can the receiver find the errors?Case Error patternNo error0000⋯⋯ 0000One error1000⋯ ..000Two errors100⋯ .001七、实验器材(设备、元器件):PC 机一台,装有 C++集成开发环境。
八、实验步骤:#include<stdio.h>#include<stdlib.h>#include<memory.h>#include<string.h>#include<conio.h>#include<time.h>#define NO_ERROR 1#define ONE_ERROR 2#define TWO_ERROR 3#define RANDOM_ERROR 4#define RESULT 1#define CRC 0#define Parity 0#define check 1int flag_parity;// 判断奇偶校验void ByteToBit(char* out,const char* in,int bits);void input_message(char*message);int xor(char **p, char *d,int len);char *crc_function(char *str_p,int len,char *dividend,int len_d,int type,char *crc_p ); char Parity_check(char *message_output,int length,int mode);void main(){ int pattern = 0;int channel_way =0;char message[8]={NULL};// data that produced by chancechar message_output[1000] = {NULL};char message_crc[] = {NULL};//transportint length;//message's length/* 这是固定了为 4 为的crc,当这里改变是就可以直接改变crc 的长度了*/ char dividend[]="10011";char message_input[1000]="";/* 这里可以更改数值当时16 为 crc 的时候,此时的len_d 为 15*/int len_d=5;//被除数长度设置char flag;while (true){ fflush(stdin); //任意输入数据printf("please input the message!\n");gets(message);printf("A need to send this message:%s\n",message);length = strlen(message);ByteToBit(message_output,message,length*8);for(int k = 0;k<length*8;k++){ printf("%d",message_output[k]);message_input[k] = message_output[k]+48;}pattern = 0;channel_way =0;printf("\n");printf("Coding on error dectecting algorithms\n");printf(" 1.Cyclic redundancy check\n");printf(" 2.Parity check \n");printf("please chice pattern: \n");/* 选择进入的检错模式 */scanf("%d",&pattern);fflush(stdin);// 清空缓存区if(pattern == 1){printf("*************************************\n");printf(" analog channel\n"); printf(" please choicethe way of error\n"); printf("**** 1.No error *****\n");printf("**** 2.One error *****\n"); printf("**** 3.Twoerrors *****\n"); printf("**** 4.Random errors *****\n");scanf("%d",&channel_way); printf("\ncrc :");//进行 crc 检测int len = length*8;//printf("%d\n",len);char *crc = NULL;crc = crc_function(message_input,len,dividend,len_d,CRC,NULL);for(int i = 0;i < len_d;i++){printf("%c",*crc);message_input[length*8+i] = *crc;crc+=1;}printf("\n");/* 模拟信道Case Error patternNo error0000⋯⋯ 0000One error1000⋯ ..000Two errors100⋯ .001Random errors Random error pattern*/if(channel_way == NO_ERROR){char *result = NULL;int flagg=0;printf(" 信道中传输数据: ");for(int f =0;f<length*8+len_d-1 ;f++)printf("%c",message_input[f]);printf("\n");printf(" 正在检错中 .......\n");printf(" 检错结果: ");fflush(stdin);result =crc_function(message_input,len,dividend,len_d,RESULT,crc-len_d);for(int i = 0;i < len_d-1;i++){printf("%c",*result);if((*result) - 48 != 0){printf("\nerror! \n");flagg =1;break;}result+=1;}if(flagg == 0)printf("\n no error! \n");}if(channel_way == ONE_ERROR){char *result = NULL;message_input[0] = ((message_input[0] - 48)^('1'-48)) + 48;printf(" 信道中传输数据: ");for(int f =0;f<length*8+len_d-1 ;f++)printf("%c",message_input[f]);printf("\n");printf(" 正在检错中 .......");printf(" 检错结果: ");= resultcrc_function(message_input,len,dividend,len_d,RESULT,crc-len_d);for(int i = 0;i < len_d-1;i++){if(*result == '1'){printf("data error! \n");break;}else{continue;result+=1;}}}if(channel_way == TWO_ERROR){char *result = NULL;message_input[0] = ((message_input[0] - 48)^('1'-48)) + 48;message_input[length*8-1] =((message_input[length*8-1]-48)^('1'-48)) + 48;printf(" 信道中传输数据: ");for(int f =0;f<length*8+len_d-1 ;f++)printf("%c",message_input[f]);printf("\n");printf(" 正在检错中 .......");printf(" 检错结果: ");= resultcrc_function(message_input,len,dividend,len_d,RESULT,crc);for(int i = 0;i < len_d-1;i++){if(*result != '0'){printf(" data error! \n");break;}else{continue;result+=1;}}}if(channel_way == RANDOM_ERROR){char *result = NULL;int no;srand( (unsigned)time( NULL ) );//初始化随机数no = rand()%length*8;message_input[no] = ((message_input[0] - 48)^('1'-48)) + 48;printf(" 信道中传输数据: ");for(int f =0;f<length*8+len_d-1 ;f++)printf("%c",message_input[f]);printf("\n");printf(" 正在检错中 .......\n");printf(" 检错结果: ");result= crc_function(message_input,len,dividend,len_d,RESULT,crc);for(int i = 0;i < len_d-1;i++){if(*result != '0'){printf(" data error! \n");break;}else{continue;result+=1;}}}printf("************************************\n");printf("\n");printf("\n");}else{printf("Please select the parity mode\n");printf(" 1.Even parity \n");printf(" 2.Odd parity\n");scanf("%d",&flag_parity);char m = Parity_check(message_input,length*8,Parity);printf(" 在信道中传输的 message:");message_input[length*8] = m;for(int message_number= 0;message_number<=length*8;message_number++)printf("%c",message_input[message_number]);printf("\n");printf("*************************************\n");printf("******analog channel******\n");printf("***please choice the way of error****\n");printf("**** 1.No error*****\n");printf("**** 2.One error*****\n");printf("**** 3.Two errors*****\n");scanf("%d",&channel_way);if(channel_way == NO_ERROR){for(int f =0;f<length*8;f++)printf("%c",message_input[f]);printf(" 正在检错中 .......\n");printf(" 检错结果: ");char flag_parity_mode =Parity_check(message_input,length*8,check);if(flag_parity_mode == (message_input[length*8]))printf("no error!\n");}if(channel_way == ONE_ERROR){message_input[0] = ((message_input[0] - 48)^('1'-48)) + 48;for(int f =0;f<length*8;f++)printf("%c",message_input[f]);printf(" 正在检错中 .......\n");printf(" 检错结果: ");char flag_parity_mode =Parity_check(message_input,length*8,check);printf(" error!\n");}if(channel_way == TWO_ERROR){message_input[0] = ((message_input[0] - 48)^('1'-48)) + 48;message_input[length*8-1] = ((message_input[length*8-1] -48)^('1'-48)) + 48;for(int f =0;f<length*8;f++)printf("%c",message_input[f]);printf(" 正在检错中 .......\n");printf(" 检错结果: ");char flag_parity_mode =Parity_check(message_input,length*8,check);printf("no error!\n");}printf("************************************\n");printf("\n");printf("\n");}fflush(stdin);printf("do you want to continue? y/n\n");scanf("%c",&flag);if(flag == 'y')continue;elsebreak;}}/***********************************************/function :完成字节转换成位的功能/输入字符: In输出的二进制:Out************************************************/void ByteToBit(char* out,const char* in,int bits){//char out_1[1000] = "";int i;//printf("%s\n",in);for(i=0;i<bits;++i){out[bits-i-1]=(in[i>>3]>>(i&7))&1; //printf("%d:%d\n",i,out[i]);}}/*********************************************** /function :完成异或除法/输入: **p *d/输出:直接将一次异或除法之后的结果覆盖************************************************/ int xor(char **p, char *d,int len=5){//p 为 message,d 为 crc 检测的中的 pint i=0;for(;i<len;i++){**p=(**p-48)^(*d-48)+48;*p=*p+1;d=d+1;}d=d-len;//d 重新指向最新的//*p=*p-len+1;//p 后移一位return 0;}/*********************************************** /function :完成 crc 检错以及 crc 计算/输入:传输字符: str_p 传输字符长度 len/ /4 位的 crc 的检错方式len_d 是需要填 0 的个数type 用于判断显示计算传输之后的结果还是计算crc/输出: crc 或者计算传输之后的结果************************************************/char *crc_function(char *str_p,int len,char *dividend,int len_d,int type,char *crc_p=NULL){int i;int j;char *input_p=(char *)malloc(sizeof(char)*(len+len_d-1)); //申请空间char *input_p_tmp=NULL;input_p_tmp=input_p;//向指针指向的内存里存数据for(i=0;i<len;i++){*input_p_tmp=str_p[i];input_p_tmp++;}/* 补零个数为 len_d-1*/for(i=0;i<len_d-1;i++){if(type==CRC){//如果是求 crc 就补 0*input_p_tmp='0';input_p_tmp++;}else{//如果是求结果就补crc*input_p_tmp=*crc_p;crc_p++;input_p_tmp++;}}input_p_tmp=NULL;//开始检查如果是 1 则进行异或除法 ,如果是 0 就指针向下移动一位 .其中 '0'=48for(j=0;j<len;j++){/*把 1 传入48表示为 "0";*/if(*input_p==48){//指针后移一位input_p=input_p+1;}else{xor(&input_p,dividend,len_d);}}return input_p;}/***********************************************/function :完成奇偶校验/输入:message_output为需要传输的数据以及数据的长度lengh 奇偶校验的模式/输出:返回奇偶校验的结果************************************************/char Parity_check(char *message_output,int length,int mode) {fflush(stdin);int j = 0;//偶校验if(flag_parity== 1){ if(mode == Parity){ for(int i = 0;i<length;i++){ if(message_output[i] == 49)j++;elsecontinue;}if(j%2 == 0)return '0';elsereturn '1';}else{ for(int i = 0;i<length;i++){if(message_output[i] == 49)j++;else continue;}if(j%2 == 0)return '0';elsereturn '1';}}//奇校验else if(flag_parity == 0){if(mode == Parity){for(int i = 0;i<length;i++){if(message_output[i] == 49)j++;elsecontinue;}if(j%2 == 1)return '0';elsereturn '1';}else{for(int i = 0;i<length;i++){if(message_output[i] == 49)j++;elsecontinue;}if(j%2 == 1)return '0';elsereturn '1';}}}九、实验数据及结果分析:1.输入界面2.输入数据3. CRC 校验1)No error 2)One error3)Two errors 4)Random errors4.奇偶校验①界面②Even parity 1)No error2)One error③Odd parity1)No error3)Two errors十、实验结论:奇偶校验, 1 位错可发现, 2 位错不可发现(奇数个错可发现,偶数个错不可发现)。