FX读写CRC校验程序要独立写两个吗

FX读写CRC校验程序要独立写两个吗,第1张

不一定。CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

用CRC校验来实现判断自身完整性的,这种办法是先取得一个原始的crc值,再通过运行后取得现在的crc值,两者比对,如果一致就视为软件没有被修改,否则就视为修改了。

从你上面的代码片段来看,获取crc值的功能已经有了,下一步需要将这个与原始值进行比较,这个原始值通常要保存在外部(因为这个值在编译之前是未知的),过程可以这样:首先,代码先编写完成,比如:

if crc<>0 then

begin

Edit2Text:=PChar(IntToHex(crc,6));

if Edit2Text = GetMyCrc() then

//如果校验相等

else

//如果校验不相等……

end;

编译完成后,获取这个文件的CRC码(你上面的Edit2Text),将这个值保存到这个值你可以保存到文件、注册表等等地方,还可以将这个值进行加密处理。

GetMyCrc()这个函数的功能,是取得你保存的文件、注册表等等地方CRC值,取得后,再跟现在的CRC值进行比较就可以了。

为保证传输过程的正确性,需要对通信过程进行差错控制。差错控制最常用的方法是自动请求重发方式(ARQ)、向前纠错方式(FEC)和混合纠错(HEC)。在传输过程误码率比较低时,用FEC方式比较理想。在传输过程误码率较高时,采用FEC容易出现“乱纠”现象。HEC方式则是ARQ和FEC的结合。在许多数字通信中,广泛采用ARQ方式,此时的差错控制只需要检错功能。实现检错功能的差错控制方法很多,传统的有:奇偶校验、校验和检测、重复码校验、恒比码校验、行列冗余码校验等,这些方法都是增加数据的冗余量,将校验码和数据一起发送到接受端。接受端对接受到的数据进行相同校验,再将得到的校验码和接受到的校验码比较,如果二者一致则认为传输正确。但这些方法都有各自的缺点,误判的概率比较高。

循环冗余校验CRC(Cyclic Redundancy Check)是由分组线性码的分支而来,其主要应用是二元码组。编码简单且误判概率很低,在通信系统中得到了广泛的应用。下面重点介绍了CRC校验的原理及其算法实现。

CRC校验可以100%地检测出所有奇数个随机错误和长度小于等于k(k为g(x)的阶数)的突发错误。所以CRC的生成多项式的阶数越高,那么误判的概率就越小。

CRC代码的一些基本概念和运算:

CRC多项式:

例:

代码:1010111 对应的多项式为:X6+X4+X2+X+1

多项式X5+X3+X2+X1+1对应的代码为101111

CRC生成多项式:

首位和最后一位必须是1。CRC生成多项式是给定的,在传输过程中不变,即发送和接收端生成码相同。

一些常用的校验码为:

CRC8=X8+X5+X4+1

CRC-CCITT=X16+X12+X5+1

CRC16=X16+X15+X5+1

CRC12=X12+X11+X3+X2+1

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

CRC的运算本质是异或运算(模2除法)

例:原信息码为1011001

生成码为11001

校验码计算过程

① 将信息码左移4位(生成码长-1);得到10110010000

② 异或运算

10110010000

11001

01111010000(前面的数进行异或运算,后面的直接抄下来)

11001

0011110000(和生成码异或运算的必须从1开始)

11001

00111000

11001

001010

这样得到的结果为1010,即为所需要的校验码,添加到信息码后,得到发送的代码为:

10110011010

我把上面的手算过程用c#写了一段程序,如下:

using System;

namespace mainClass

{

public class mainProgress

{

public static void Main()

{

byte[] msg={1,0,1,1,0,0,1};//信息码

byte[] gmsg=new byte[msgLength+4];

crc c = new crc();

gmsg=ccode(msg);

ConsoleWrite("编码后字符串为:");

for (int i = 0; i < gmsgLength; i++)

{

ConsoleWrite("{0}", gmsg[i]ToString());

}

ConsoleWrite("\n");

byte[] gmsg1={ 1, 0, 1, 1, 0, 1, 1 };//接收到的代码

bool r = cdet(gmsg1);

if (r)

{

ConsoleWriteLine("传输正确");

}

else

{ ConsoleWriteLine("传输错误"); }

}

}

public class crc//CRC编码类

{

private byte[] g = { 1,1,0,0,1};//生成码

public byte[] code(byte[] msg)//编码

{

byte[] gmsg=new byte[gLength+msgLength-1];

msgCopyTo(gmsg, 0);//

for (int i = 0; i < msgLength; i++)//完成异或运算,即模2除法

{

if (gmsg[i] == 1)

{

for (int j = 0; j < gLength; j++)

{

if (gmsg[i + j] == g[j])

gmsg[i + j] = 0;

else

gmsg[i + j] = 1;

}

}

}

msgCopyTo(gmsg, 0);

return gmsg;

}

private bool f=true;

//接收端检测

public bool det(byte[] gmsg)

{

for (int i = 0; i < gmsgLength - gLength+1; i++)

{

if(gmsg[i]==0)

continue;

for (int j = 0; j < gLength; j++)

{

if (gmsg[i + j] == g[j])

gmsg[i + j] = 0;

else

gmsg[i + j] = 1;

}

}

for (int i = 0; i < gmsgLength; i++)

{

if (gmsg[i] == 1)

f = false;

}

return f;

}

}

}

using System;

using SystemCollectionsGeneric;

using SystemLinq;

using SystemText;

namespace ConvertToCRC16

{

public static class CRC16Util

{

// CRC高位字节表

private static readonly byte[] m_CRCHighOrderByteTable = new byte[]

{

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40

};

// CRC低位字节表

private static readonly byte[] m_CRCLowOrderByteTable = new byte[]

{

0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,

0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,

0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,

0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,

0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,

0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,

0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,

0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,

0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,

0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,

0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,

0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,

0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,

0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,

0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,

0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,

0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,

0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,

0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,

0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,

0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,

0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,

0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,

0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,

0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,

0x43, 0x83, 0x41, 0x81, 0x80, 0x40

};

/// <summary>

/// 获得CRC16效验码

/// </summary>

/// <param name="buffer"></param>

/// <returns></returns>

public static void CalculateCrc16(byte[] buffer, out byte crcHighOrderByte, out byte crcLowOrderByte)

{

// CRC高位字节/低位字节

crcHighOrderByte = crcLowOrderByte = 0xff;

for (int i = 0; i < bufferLength; i++)

{

// 计算CRC查找索引

int crcIndex = crcHighOrderByte ^ buffer[i];

crcHighOrderByte = (byte)(crcLowOrderByte ^ m_CRCHighOrderByteTable[crcIndex]);

crcLowOrderByte = (byte)m_CRCLowOrderByteTable[crcIndex];

}

}

}

}

// 工具函数如上

程序问题,CRC错误是程序自带的一个自校验程序,可以自动检验你所安装的程序是否跟原程序一致,如果不一致就会出现CRC错误,建议你换个网站下 你的问题 是所有的文件都这样? 那就是你电脑的问题 100%确定你的内存有问题,可能是不兼容,或是坏了特别是两根内存最可能出现这种情况,检查主板bios或做成单通道都可以解决

unsigned short crc_dsp(unsigned short reg, unsigned char data_crc)

//reg为crc寄存器, data_crc为将要处理的8bit数据流

{

unsigned short msb; //crc寄存器将移出的最高1bit

unsigned short data;

unsigned short gx = 0x8005, i = 0; //i为左移次数, gx为生成多项式

data = (unsigned short)data_crc;

data = data << 8;

reg = reg ^ data;

do

{

msb = reg & 0x8000;

reg = reg << 1;

if(msb == 0x8000)

{

reg = reg ^ gx;

}

i++;

}

while(i < 8);

return (reg);

}

以上就是关于FX读写CRC校验程序要独立写两个吗全部的内容,包括:FX读写CRC校验程序要独立写两个吗、怎么用CRC实现 软件自身的完整性检查功能 Delphi、关于CRC效验等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9744304.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存