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代码编辑的最后加工路径已经不能直接对编辑的 ...
随机推荐
- js中的事件冒泡
事件冒泡和阻止事件冒泡: 事件冒泡的原理:从实际操作的元素(事件)向上级父元素一级一级执行下去,直到达到document/window,冒泡过程结束.例如:假设我有一个 div 盒子,里面嵌套了1个子 ...
- Ceph 文件系统 CephFS 的实战配置,等你来学习 -- <4>
Ceph 文件系统 CephFS 的介绍与配置 CephFs介绍 Ceph File System (CephFS) 是与 POSIX 标准兼容的文件系统, 能够提供对 Ceph 存储集群上的文件访问 ...
- 用python做推荐系统(二)
一.简介 继上一篇基于用户的推荐算法,这一篇是要基于商品的,基于用户的好处是可以根据用户的评价记录找出跟他兴趣相似的用户,再推荐这些用户也喜欢的电影,但是万一这个用户是新用户呢?或是他还没有对任何电影 ...
- solr学习(一)安装与部署
经过测试,同步MongoDB数据到Solr的时候,Solr版本为8.4.0会出现连接不上的错误,8.3.0未经测试不知,博主测试好用的一版为8.2.0,但是官网已经下不到了,所以我会把下载链接放在文末 ...
- docker 修改实例名称
docker 容器(服务)重命名只要一个命令就可以: docker rename 原容器名 新容器名 如:
- JS 中检测数组的四种方法
今天和大家分享一下 JS 中检测是不是数组的四种方法,虽然篇幅不长,不过方法应该算是比较全面了. 1. instanceof 方法 instanceof 用于检测一个对象是不是某个类的实例,数组也是一 ...
- 动态规划最短路径LintcodeNO110
动态规划最短路径LintcodeNO110 简单的dp题,没啥好说的... class Solution { public: /** * @param grid: a list of lists of ...
- Task 线程重用导致等待!
测试代码: ; i < ; i++) { var d = DateTime.Now; Task.Run(() => { Console.WriteLine($"{Thread.C ...
- 求树上任意一点所能到达的最远距离 - 树上dp
A school bought the first computer some time ago(so this computer's id is 1). During the recent year ...
- Scala 学习(4)之「类——基本概念2」
目录 内部类 extends override和super override field isInstanceOf和asInstanceOf getClass和classOf 内部类 import s ...