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代码编辑的最后加工路径已经不能直接对编辑的 ...
随机推荐
- Python基础复习函数篇
目录 1.猴子补丁2. global和nonlocal关键字3.迭代器和生成器4.递归函数5.高阶函数和lamdba函数6.闭包7.装饰器 1. 猴子补丁 猴子补丁主要用于在不修改已有代码情况下修 ...
- 手写vue observe数据劫持
实现代码: class Vue { constructor(options) { //缓存参数 this.$options = options; //需要监听的数据 this.$data = opti ...
- Redis实战 | 持久化、主从复制特性和故障处理思路
前言 前面两篇我们了解了Redis的安装.Redis最常用的5种数据类型.本篇总结下Redis的持久化.主从复制特性,以及Redis服务挂了之后的一些处理思路. 前期回顾传送门: Linux下安装Re ...
- Qt中设置窗口图标
转:https://blog.csdn.net/weiren2006/article/details/7438028 1.通过qtcreator新建一个文件filename.qrc,将图片添加到fil ...
- 人脸识别系统 —— 基于python的人工智能识别核心
起因 自打用python+django写了一个点菜系统,就一直沉迷python编程.正好前几天公司boss要我研究一下人脸识别,于是我先用python编写了一个人脸识别系统的核心,用于之后的整个系统. ...
- 第7节class与style绑定
方法一 效果图: 方法二 效果图: 方法三 效果图: 代码: <!DOCTYPE html> <html lang="en" xmlns:v-bind=&qu ...
- django restful 序列化
https://www.cnblogs.com/wt7018/p/11456440.html https://www.cnblogs.com/wt7018/p/11530962.html
- python self用法
在定义类的过程中,无论是显式的创建类的构造方法,还是向类中添加实例方法,都要将self参数作为方法的第一个参数. class Person: def __init__(self): print(&qu ...
- ELK实战-elasticsearch安装
操作系统: centos版本 7.4 防火墙 关闭 selinux 关闭 elasticsearch版本 6.3.2 java版本 1.8 server1 192.168.10.126 server2 ...
- FluentData -Micro ORM with a fluent API that makes it simple to query a database
Code samples Create and initialize a DbContextThe connection string on the DbContext class can be in ...