CRC循环冗余检测C语言实现----花了几天时间乱写的
由于笔者目前正在上计算机网络的课,老师要我们编一下crc的循环检测过程,所以我想着刚好在学c,那就随便看看写不写的了,首先百度了一下网上资料,基本都是用位移运算符实现的,由于本人懒得去看一下位移运算,就用数组存储1,0,凑合一下,采用元素整体往前移1位的思想,看看能不能实现,最后似乎是写出来了,但是写的很杂乱。别人用几十行写的,用了位移运算符,我没用,而是用其它方式实现,写了几百行,虽然说几百行,里面的代码复用率也很高了,没有去封装成一个函数来调用是本次实验的一大不足。现在就在此记录一下我的浅陋的代码,供我以后查看。
如被各位前辈看到,就当没看见吧,因为实在惨不忍睹……
#include "stdio.h"
#include <string.h> #define max 50
char data[max];
int data_10[max];//定义是数据的10进制数组
int data_2[max];//定义数据的2进制数组
int redata_2[max];//定义加上余数的数据的2进制数组
int data_2_del[max];//定义保存除数的2进制数组
int data_2_yushu[max];//定义保存余数的2进制数组
int i, sum_10;//sum_10是10进制数组里面各个数字的和
int strLength;//定义数据长度
int strLength_2;//定义数据二进制长度
int restrLength_2;//定义拼接余数的数据二进制长度
int strLength_del;//定义除数二进制长度
int x, n, index = ;//定义x,用来接收十进制和sum_10 int pow(int a, int b);//定义乘方函数
int input();//定义输入函数
void change_two();//定义转二进制函数
void div_2();//定义模2运算 int main()
{ input();//输入函数
change_two();//数据转二进制
div_2();
}
//乘方函数
int pow(int a, int b) {
int SUM=;
for (int i = ; i <= b;i++) {
SUM= a * SUM;
}
return SUM;
}
//定义输入函数
int input() {
printf("请输入一组数据:");
//这里使用gets才可以计算空格的字符串长度,使用scanf的话,遇到空格就结束了,而gets一次读一行。确保使用strlen时计算正确
gets(data);
for (i = ; i < ; i++)
{//因为ASCII码就是以10进制的方式表示的,所以直接赋值给整型数组
data_10[i] = data[i];
}
//获取字符数组里面的存储长度,赋值给strLength
strLength = strlen(data);
printf("字符串的长度为:%d\n", strLength);
printf("您输入的字符对应的ASCII码为:");
for (i = ; i < strLength; i++) {
printf("%d,", data_10[i]);
//将字符数组存储到整型数组里面,再逐个输出
sum_10 = sum_10 + data_10[i];
} return ;
}
//定义十进制转二进制的函数
void change_two() {
x = sum_10;
n = ;
int data_2_zhenxu[];
for (i = ; i < ; i++)
{
data_2[i] = ;//初始化数据data,使其全部为0
} printf("\AsCII码总和为:%d,对应的%d进制为:", x, n); // n=2,表示二进制
while (x > )
{
data_2[index] = x % n;
x = x / n;
index++;
}
int Index = index;
for (i = ; i <= Index - ; i++) {
data_2_zhenxu[i] = data_2[index-];
index--;
}
for (i = ; i <=Index - ; i++) {
data_2[i] = data_2_zhenxu[i];
}
for (i = ; i <= Index - ; i++) {
redata_2[i] = data_2_zhenxu[i];
}
for (i = ; i <=Index - ; i++)
printf("%d", data_2[i]);
strLength_2 = Index;
printf("\n");
}
//模2运算,采用数组方式存储1,0数字
/*1.进行模二运算前,先比较除数长度,必须小于输入的数据长度才可以运算
*2.每次运算数据的二进制长度都-1,然后依次比较数组的第一位到第strLength_del位,strLength_del是除数的二进制个数
*3.输出计算后的余数,再拼接到原数据上
*4.用拼接后的数据的二进制数再次于除数做模二运算,若余数为0,输出数据结果正确
*/
void div_2() {
/*for (i = index - 1; i >= 0; i--)
printf("%d", data_2[i]);*/
restrLength_2 = strLength_2;
int Max = max;//把50赋值给Max
int z;
int *tempdata;//为什么定义整型指针来实现整型数组
int *tempArry;
printf("请输入除数的二进制数个数(请观察数据的二进制长度,必须长度小于数据的长度):");
scanf("%d", &z);
tempdata = (int*)malloc(sizeof(int)*z);
tempArry = (int*)malloc(sizeof(int)*z);
getchar();
for (i = ; i < z; i++) {
tempArry[i] = ;
}
for (i = ; i < z; i++) {
printf("\n请输入第%d个数字:", i + );
scanf("%d", &tempdata[i]);
getchar();
}
printf("您输入的二进制为:");
for (i = ; i < z; i++) {
printf("%d", tempdata[i]);
}
for (int i = ; i <z; i++) {
data_2_del[i] = tempdata[i];
}
strLength_del = z;
for (i = strLength_2; i < (strLength_2 + z-); i++) {
data_2[i] = ;
}
int hmy = (strLength_2 + z );
printf("\n重新生成后的数据为:");
for (i = ; i < (strLength_2 + z - ); i++) {
printf("%d", data_2[i]);
}
printf("\n除数二进制位长度:%d\n", strLength_del);
printf("除数二进制位:");
for (int i = ; i < strLength_del; i++) { printf(":%d", data_2_del[i]); }
for (int i = ; i < strLength_del; i++) { tempArry[i] = ; }
if (strLength_del > (strLength_2 + z )) {
printf("除数不合法,请重新输入!\n");
div_2();
}
else
{
printf("下面开始进行模二运算!\n");
printf("----------------------------------------------\n");
while (hmy >=strLength_del) {
int strLength_del2 = strLength_del ;
int dataSum = ;//定义数据前几位拼成的整型数据大小;
int del_Sum = ;//定义除数前几位拼成的整型数据大小
//每次进行模2运算前,都要比较前几位拼成的整数大小
for (int j = ; j <; j++) {
strLength_del2--;
dataSum += data_2[j] * pow(, strLength_del2);
del_Sum += data_2_del[j] * pow(, strLength_del2);
printf("strLength_del2=%d\n", strLength_del2);
printf("datasum=%d,delsum=%d\n", dataSum, del_Sum);
}
/*printf("datasum=%d,delsum=%d", dataSum, del_Sum);*/
if (dataSum = del_Sum) {
int count = ;
for (; count < strLength_del; count++) {
if (data_2[count] == data_2_del[count]) {
data_2[count] = ;
if ((count+) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
data_2[i] = data_2[i + ];//数组数据前移
}
Max--;
hmy--;//数据实际长度-1
printf("测试\n");
}
}
else {
data_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
data_2[i] = data_2[i + ];
}
Max--;
hmy--;//数据实际长度-1
printf("测试\n");
} }
}//
}
else {
/*printf("datasum<del_sum;");*/
int count = ;
for (; count < strLength_del; count++) {
if (tempArry[count] == data_2_del[count]) {
data_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
data_2[i] = data_2[i + ];//数组数据前移
}
Max--;
hmy--;//数据实际长度-1
printf("测试\n");
}
}
else {
data_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
data_2[i] = data_2[i + ];
}
Max--;
hmy--;//数据实际长度-1
printf("测试\n");
} }
}//
} }
//输出余数二进制
for (int i = ; i < max; i++) {
data_2_yushu[i] = data_2[i];
}
printf("\n余数二进制为:");
for(i=;i< strLength_del-;i++)
printf("%d", data_2_yushu[i]);
}
int j;
int HMY = restrLength_2 + z;
for (i = (restrLength_2),j=; i < (restrLength_2+z-);j++, i++) {
redata_2[i] = data_2_yushu[j];
}
printf("\n拼上余数后的数据为:");
for (i = ; i < (restrLength_2+z-); i++) {
printf("%d",redata_2[i]);
}
printf("\n除数二进制位:");
for (int i = ; i < strLength_del; i++) { printf(":%d", data_2_del[i]); }
printf("\n下面进行循环冗余检测:\n");
printf("***************************************************\n");
while (HMY>= strLength_del) {
int strLength_del2 = strLength_del;
int dataSum = ;//定义数据前几位拼成的整型数据大小;
int del_Sum = ;//定义除数前几位拼成的整型数据大小
//每次进行模2运算前,都要比较前几位拼成的整数大小
//这里不用比较大小,比较看看有没有相同位数就好
for (int j = ; j <; j++) {
strLength_del2--;
dataSum += redata_2[j] * pow(, strLength_del2);
del_Sum += data_2_del[j] * pow(, strLength_del2);
printf("strLength_del2=%d\n", strLength_del2);
printf("datasum=%d,delsum=%d\n", dataSum, del_Sum);
}
/*printf("datasum=%d,delsum=%d", dataSum, del_Sum);*/
if (dataSum = del_Sum) {
int count = ;
for (; count < strLength_del; count++) {
if (redata_2[count] == data_2_del[count]) {
redata_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
redata_2[i] = redata_2[i + ];//数组数据前移
}
Max--;
HMY--;//数据实际长度-1
printf("测试\n");
}
}
else {
data_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
redata_2[i] = redata_2[i + ];
}
Max--;
HMY--;//数据实际长度-1
printf("测试\n");
} }
}//
}
else {
/*printf("datasum<del_sum;");*/
int count = ;
for (; count < strLength_del; count++) {
if (tempArry[count] == data_2_del[count]) {
redata_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
redata_2[i] = redata_2[i + ];//数组数据前移
}
Max--;
HMY--;//数据实际长度-1
printf("测试\n");
}
}
else {
redata_2[count] = ;
if ((count + ) % strLength_del == ) {
for (int i = ; i < Max - ; i++) {
redata_2[i] = redata_2[i + ];
}
Max--;
HMY--;//数据实际长度-1
printf("测试\n");
} }
}//
}
}
int crcSum = ;
printf("检测后的数据为:");
for (i = ; i < max; i++) {
printf("%d", redata_2[i]);
crcSum += redata_2[i];
}
if (crcSum==) {
printf("\n");
printf("\nCRC检测无误!><!!!!!!!!!");
}
}
CRC循环冗余检测C语言实现----花了几天时间乱写的的更多相关文章
- Redis源代码分析(23)--- CRC循环冗余算法RAND随机数的算法
他今天就开始学习Redis源代码的一些工具来实现,在任何一种语言工具.算法实现的原理应该是相同的,一些比較经典的算法.比方说我今天看的Crc循环冗余校验算法和rand随机数产生算法. CRC算法全称循 ...
- crc循环冗余校验
循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误.它 ...
- 曹工杂谈:花了两天时间,写了一个netty实现的http客户端,支持同步转异步和连接池(1)--核心逻辑讲解
背景 先说下写这个的目的,其实是好奇,dubbo是怎么实现同步转异步的,然后了解到,其依赖了请求中携带的请求id来完成这个连接复用:然后我又发现,redisson这个redis客户端,底层也是用的ne ...
- LRC CRC 纵向冗余码校验
LRC CRC 纵向冗余码校验 2010-01-26 11:00:15| 分类: 电气 | 标签: |字号大中小 订阅 1.LRC校验 LRC域是一个包含一个8位二进制值的字节.LRC值由 ...
- QT国际化示例, 检测系统语言,设置适合语言,按键切换显示语言
1.效果如下图,开启就自动检测系统语言,选择系统语言显示, UI有控件设置,在中文和英文之间切换.. 2. 源码 dialog.h #ifndef DIALOG_H #define DIALOG_H ...
- FastJson禁用循环引用检测
我们先来看一个例子: package com.elong.bms; import java.io.OutputStream; import java.util.HashMap; import java ...
- 【生产问题】记还原一个很小的BAK文件,但却花了很长时间,分析过程
[生产问题]还原一个很小的BAK文件,但却花了很长时间? 关键词:备份时事务日志太大会发生什么?还原时,事务日志太大会怎么办? 1.前提: [1.1]原库数据已经丢失,只有这个bak了 [1.2]ba ...
- C语言--乱写C语言
C语言的语法太枯燥了 换个写法 #include <stdio.h> #include<stdlib.h> #define end } #define if(x) if ( ...
- 花了一年时间完成的 在线G代码编辑,加工系统 G-Code Editor V1.0
G代码是数控程序中的加工指令.一般都称为G指令.可以直接用来驱动机床,各种控制系统.是一种数控行业标准.传统的G代码编写以及编辑无法在线编辑,也不能实时看到g代码编辑的最后加工路径已经不能直接对编辑的 ...
随机推荐
- 让你彻底明白TCP三次握手,四次挥手
今天我们来讲一下TCP的三次握手和四次挥手,先来张思维导图. 一.TCP是什么 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流 ...
- MacBook Pro 入手一年了,到底香不香?
最近又有小伙伴问到底值不值得入手一台 MacBook Pro,松哥自己在 2018 年 10 月份的时候入手了一台,到现在为止,也用了一年多了,今天就来和小伙伴们聊一聊使用感受,至于到底值不值,需要大 ...
- Django之models字段属性
目录 常用字段 AutoField IntegerField CharField 自定义及使用char DateField DateTimeField 字段合集 字段参数 null unique db ...
- c语言一道题
C语言中,a=b=c,a=b==c,a==(b=c),a==(b==c)有什么区别 main(){inta=1,b=2,c=3;printf("%d,%d,%d,%d\n",a=b ...
- C# 把文件夹下所有文件添加到集合中
private List<string> FindFile(string Path) { List<string> list=new List<string>(); ...
- 用VSCode插件来一键填满Github的绿色格子吧-AutoCommit
autoCommit 一个用于Git自动commit的VSCode插件,它可以用来补充之前忘记提交commit,帮助你把首页的绿色格子填满. 使用效果 使用本插件来控制commit次数. 如下图,你甚 ...
- Netty之缓冲区ByteBuf解读(一)
Netty 在数据传输过程中,会使用缓冲区设计来提高传输效率.虽然,Java 在 NIO 编程中已提供 ByteBuffer 类进行使用,但是在使用过程中,其编码方式相对来说不太友好,也存在一定的不足 ...
- 逆元(inv)
推荐博客 : http://blog.csdn.net/baidu_35643793/article/details/75268911 通常我们在计算除法取模时,并不能直接的取模后再去相除,答案会有问 ...
- hdu6638 线段树求最大子段和
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6638 Problem Description There are n pirate chests bu ...
- spring boot 集成apollo 快速指南
目前市面上流行的三大配置中心框架:Spring CLoud Config .Alibaba Nacos 以及携程apollo, 我们相应架构组号召,就使用Apollo吧. Work Flow 简单解释 ...