CRC码的编码和解码程序是什么?

CRC码的编码和解码程序是什么?,第1张

我有一个别人变得CRC程序,其中有好几种CRC的编码方法,也许会有用

using System

namespace Communication.IO.Tools

{

/// <summary>

/// Tool to calculate and add CRC codes to a string

///

/// ***************************************************************************

/// Copyright (c) 2003 Thoraxcentrum, Erasmus MC, The Netherlands.

///

/// Written by Marcel de Wijs with help from a lot of others,

/// especially Stefan Nelwan

///

/// This code is for free. I ported it from several different sources to C#.

///

/// For comments: [email protected]

/// ***************************************************************************

/// </summary>

public class CRCTool

{

// 'order' [1..32] is the CRC polynom order, counted without the leading '1' bit

// 'polynom' is the CRC polynom without leading '1' bit

// 'direct' [0,1] specifies the kind of algorithm: 1=direct, no augmented zero bits

//孙态基 'crcinit' is the initial CRC value belonging to that algorithm

/闭迟/则谨 'crcxor' is the final XOR value

// 'refin' [0,1] specifies if a data byte is reflected before processing (UART) or not

// 'refout' [0,1] specifies if the CRC will be reflected before XOR

// Data character string

// For CRC-CCITT : order = 16, direct=1, poly=0x1021, CRCinit = 0xFFFF, crcxor=0refin =0, refout=0

// For CRC16: order = 16, direct=1, poly=0x8005, CRCinit = 0x0, crcxor=0x0refin =1, refout=1

// For CRC32: order = 32, direct=1, poly=0x4c11db7, CRCinit = 0xFFFFFFFF, crcxor=0xFFFFFFFFrefin =1, refout=1

// Default : CRC-CCITT

private int order = 16

private ulong polynom= 0x1021

private int direct = 1

private ulong crcinit= 0xFFFF

private ulong crcxor = 0x0

private int refin = 0

private int refout = 0

private ulong crcmask

private ulong crchighbit

private ulong crcinit_direct

private ulong crcinit_nondirect

private ulong [] crctab = new ulong[256]

// Enumeration used in the init function to specify which CRC algorithm to use

public enum CRCCode{CRC_CCITT, CRC16, CRC32}

public CRCTool()

{

//

// TODO: Add constructor logic here

//

}

public void Init(CRCCode CodingType)

{

switch( CodingType )

{

case CRCCode.CRC_CCITT:

order = 16direct=1polynom=0x1021crcinit = 0xFFFFcrcxor=0refin =0refout=0

break

case CRCCode.CRC16:

order = 16direct=1polynom=0x8005crcinit = 0x0crcxor=0x0refin =1refout=1

break

case CRCCode.CRC32:

order = 32direct=1polynom=0x4c11db7crcinit = 0xFFFFFFFFcrcxor=0xFFFFFFFFrefin =1refout=1

break

}

// Initialize all variables for seeding and builing based upon the given coding type

// at first, compute constant bit masks for whole CRC and CRC high bit

crcmask = ((((ulong)1<<(order-1))-1)<<1)|1

crchighbit = (ulong)1<<(order-1)

// generate lookup table

generate_crc_table()

ulong bit, crc

int i

if ( direct == 0 )

{

crcinit_nondirect = crcinit

crc = crcinit

for (i=0i<orderi++)

{

bit = crc &crchighbit

crc<<= 1

if ( bit != 0 )

{

crc^= polynom

}

}

crc&= crcmask

crcinit_direct = crc

}

else

{

crcinit_direct = crcinit

crc = crcinit

for (i=0i<orderi++)

{

bit = crc &1

if (bit != 0)

{

crc^= polynom

}

crc >>= 1

if (bit != 0)

{

crc|= crchighbit

}

}

crcinit_nondirect = crc

}

}

/// <summary>

/// 4 ways to calculate the crc checksum. If you have to do a lot of encoding

/// you should use the table functions. Since they use precalculated values, which

/// saves some calculating.

/// </summary>.

public ulong crctablefast (byte[] p)

{

// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.

// only usable with polynom orders of 8, 16, 24 or 32.

ulong crc = crcinit_direct

if ( refin != 0 )

{

crc = reflect(crc, order)

}

if ( refin == 0 )

{

for ( int i = 0i <p.Lengthi++ )

{

crc = (crc <<8) ^ crctab[ ((crc >>(order-8)) &0xff) ^ p[i]]

}

}

else

{

for ( int i = 0i <p.Lengthi++ )

{

crc = (crc >>8) ^ crctab[ (crc &0xff) ^ p[i]]

}

}

if ( (refout^refin) != 0 )

{

crc = reflect(crc, order)

}

crc^= crcxor

crc&= crcmask

return(crc)

}

public ulong crctable (byte[] p)

{

// normal lookup table algorithm with augmented zero bytes.

// only usable with polynom orders of 8, 16, 24 or 32.

ulong crc = crcinit_nondirect

if ( refin != 0 )

{

crc = reflect(crc, order)

}

if ( refin == 0 )

{

for ( int i = 0i <p.Lengthi++ )

{

crc = ((crc <<8) | p[i]) ^ crctab[ (crc >>(order-8)) &0xff ]

}

}

else

{

for ( int i = 0i <p.Lengthi++ )

{

crc = (ulong)(( (int)(crc >>8) | (p[i] <<(order-8))) ^ (int)crctab[ crc &0xff ])

}

}

if ( refin == 0 )

{

for ( int i = 0i <order/8i++ )

{

crc = (crc <<8) ^ crctab[ (crc >>(order-8)) &0xff]

}

}

else

{

for ( int i = 0i <order/8i++ )

{

crc = (crc >>8) ^ crctab[crc &0xff]

}

}

if ( (refout^refin) != 0 )

{

crc = reflect(crc, order)

}

crc^= crcxor

crc&= crcmask

return(crc)

}

public ulong crcbitbybit(byte[] p)

{

// bit by bit algorithm with augmented zero bytes.

// does not use lookup table, suited for polynom orders between 1...32.

int i

ulong j, c, bit

ulong crc = crcinit_nondirect

for (i=0i<p.Lengthi++)

{

c = (ulong)p[i]

if ( refin != 0 )

{

c = reflect(c, 8)

}

for (j=0x80j != 0j>>=1)

{

bit = crc &crchighbit

crc<<= 1

if ( (c &j) != 0)

{

crc|= 1

}

if ( bit != 0 )

{

crc^= polynom

}

}

}

for ( i=0(int)i <orderi++)

{

bit = crc &crchighbit

crc<<= 1

if ( bit != 0 ) crc^= polynom

}

if ( refout != 0 )

{

crc=reflect(crc, order)

}

crc^= crcxor

crc&= crcmask

return(crc)

}

public ulong crcbitbybitfast(byte[] p)

{

// fast bit by bit algorithm without augmented zero bytes.

// does not use lookup table, suited for polynom orders between 1...32.

int i

ulong j, c, bit

ulong crc = crcinit_direct

for (i = 0i <p.Lengthi++)

{

c = (ulong)p[i]

if ( refin != 0)

{

c = reflect(c, 8)

}

for ( j = 0x80j >0j >>= 1 )

{

bit = crc &crchighbit

crc <<= 1

if ( (c &j) >0 ) bit^= crchighbit

if ( bit >0 ) crc^= polynom

}

}

if ( refout >0)

{

crc=reflect( crc, order )

}

crc^= crcxor

crc&= crcmask

return(crc)

}

/// <summary>

/// CalcCRCITT is an algorithm found on the web for calculating the CRCITT checksum

/// It is included to demonstrate that although it looks different it is the same

/// routine as the crcbitbybit* functions. But it is optimized and preconfigured for CRCITT.

/// </summary>

public ushort CalcCRCITT(byte[] p)

{

uint uiCRCITTSum = 0xFFFF

uint uiByteValue

for (int iBufferIndex = 0iBufferIndex <p.LengthiBufferIndex++)

{

uiByteValue = ( (uint) p[iBufferIndex] <<8)

for ( int iBitIndex = 0iBitIndex <8iBitIndex++ )

{

if ( ( (uiCRCITTSum^uiByteValue) &0x8000) != 0 )

{

uiCRCITTSum = (uiCRCITTSum <<1 ) ^ 0x1021

}

else

{

uiCRCITTSum <<= 1

}

uiByteValue <<=1

}

}

return (ushort)uiCRCITTSum

}

#region subroutines

private ulong reflect (ulong crc, int bitnum)

{

// reflects the lower 'bitnum' bits of 'crc'

ulong i, j=1, crcout = 0

for ( i = (ulong)1 <<(bitnum-1)i != 0i>>=1)

{

if ( ( crc &i ) != 0 )

{

crcout |= j

}

j<<= 1

}

return (crcout)

}

private void generate_crc_table()

{

// make CRC lookup table used by table algorithms

int i, j

ulong bit, crc

for (i=0i<256i++)

{

crc=(ulong)i

if (refin != 0) // 'refin' [0,1] specifies if a data byte is reflected before processing (UART) or not

{

crc=reflect(crc, 8)

}

crc<<= order-8

for (j=0j<8j++)

{

bit = crc &crchighbit

crc<<= 1

if ( bit !=0 ) crc^= polynom

}

if (refin != 0)

{

crc = reflect(crc, order)

}

crc&= crcmask

crctab[i]= crc

}

}

#endregion

}

}

#include <腊穗stdio.h>

#include <string.h>

#include "stdlib.h"

unsigned int char2int(char *str)

{

unsigned int count=0, ret=0

for(count = 0count<strlen(str)count++)

{

ret = ret<<1

if('0' != str[count])

{ ret+=1}

}

return ret

}

unsigned int getR(char *str)

{

unsigned int c =0

int ret = strlen(str)-1

for(c=0c <strlen(str)c++)

{if(str[c] != '0')<br/> {return ret-c}

}

}

int getRi(unsigned int num)

{

int c =0

for(num != 0c++)

{num = num>>1}

return c

}

void CRC(char *scode, char *p, char*g )

{

unsigned int iP = char2int(p)

unsigned int iG = char2int(g)

unsigned int r= getR(g)

unsigned int code = iP <<r

unsigned int yx = code

for(getRi(yx) >隐逗= getRi(iG))

{ yx = yx ^ (iG<<(getRi(yx) - getRi(iG)))}

code += yx

itoa(code,scode,2)

}

void main() /灶局卖/定义主函数

{

char data[8]="" , bds[8]="",code[16]=""

printf("数据:")

scanf("%s", data)

printf("表达式:")

scanf("%s", bds)

CRC(code,data,bds)

printf("编码:%s",code)

}

下面我们以CRC-16为例来说明任意长度数据流的CRC校验码生成过程。我们采用将数据流分成若干个8bit字符,并由低字节到高字绝塌节传送的并行方法来求CRC校验码。具体计算过程为:用一个16bit的寄存器来存放CRC校验值,且设定其初值为0x0000;将数据流的第一个8bit与16bit的CRC寄存器的高字节相异或,并将结果存入CRC寄存器高字节;CRC寄存器左移一位,最低1bit补零,同时检查移出的最高1bit,若移出的最高1bit为0,则继续按上述过程左移,若最高1bit为1,则将CRC寄存器中的值与生成多项式码相异或,结果存入CRC寄存器值;继续左移并重复上述处理方法,直到将8bit数据处理完为止,则此时CRC寄存器中的值就是第一个8bit数据对应的CRC校验码;然后将此时CRC寄存器的值作为初值,用同样的处理方法重复上述步骤来处理下一个8bit数据流,直到将所有的8bit字符都处理完后,此刻CRC寄存器中的值即为整个数据流对应的CRC校验码。

下面示出了其计算过程的流程图:

在用C语言编写CRC校验码的实现程序时我们应该注意,生成多项式 对应的十六进制数为0x18005,由于CRC寄存器左移过程中,移出的最高位为1时与 相异或,所以与16bit的CRC寄存器对应并塌圆的生成多项式的十六进制数可用0x8005表示。下面给出并行处理8bit数据流的C源程序:

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)

}

以上为处理每一个8bit数据流的子程序,在计衫扮算整个数据流的CRC校验码时,我们只需将CRC_reg的初值置为0x0000,求第一个8bit的CRC值,之后,即可将上次求得的CRC值和本次将要处理的8bit数据作为函数实参传递给上述子程序的形参进行处理即可,最终返回的reg值便是我们所想得到的整个数据流的CRC校验值。


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

原文地址: https://outofmemory.cn/yw/12526830.html

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

发表评论

登录后才能评论

评论列表(0条)

保存