crctool.cs
来自「ecg tool kit for medical image retrieval」· CS 代码 · 共 632 行 · 第 1/2 页
CS
632 行
using System;
namespace Communication.IO.Tools
{
/// <summary>
/// Tool to calculate and add CRC codes to a string
///
/// ***************************************************************************
/// Copyright 2003-2004 Thoraxcentrum, Erasmus MC, The Netherlands.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Orignaly written by Marcel de Wijs with help from a lot of others,
/// especially Stefan Nelwan
///
/// Edited by Maarten JB van Ettinger.
///
/// This code is for free. I ported it from several different sources to C#.
///
/// For comments: Marcel_de_Wijs@hotmail.com
/// ***************************************************************************
/// </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=0; refin =0, refout=0
// For CRC16: order = 16, direct=1, poly=0x8005, CRCinit = 0x0, crcxor=0x0; refin =1, refout=1
// For CRC32: order = 32, direct=1, poly=0x4c11db7, CRCinit = 0xFFFFFFFF, crcxor=0xFFFFFFFF; refin =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 = 16; direct=1; polynom=0x1021; crcinit = 0xFFFF; crcxor=0; refin =0; refout=0;
break;
case CRCCode.CRC16:
order = 16; direct=1; polynom=0x8005; crcinit = 0x0; crcxor=0x0; refin =1; refout=1;
break;
case CRCCode.CRC32:
order = 32; direct=1; polynom=0x4c11db7; crcinit = 0xFFFFFFFF; crcxor=0xFFFFFFFF; refin =1; refout=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=0; i<order; i++)
{
bit = crc & crchighbit;
crc<<= 1;
if ( bit != 0 )
{
crc^= polynom;
}
}
crc&= crcmask;
crcinit_direct = crc;
}
else
{
crcinit_direct = crcinit;
crc = crcinit;
for (i=0; i<order; i++)
{
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 = 0; i < p.Length; i++ )
{
crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^ p[i]];
}
}
else
{
for ( int i = 0; i < p.Length; i++ )
{
crc = (crc >> 8) ^ crctab[ (crc & 0xff) ^ p[i]];
}
}
if ( (refout^refin) != 0 )
{
crc = reflect(crc, order);
}
crc^= crcxor;
crc&= crcmask;
return(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, int offset, int length)
{
// Works like crctablefast(byte[] p), except you now calculate a CRC for a specific part of the byte array.
// 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 (offset < 0)
offset = 0;
length += offset;
if (length > p.Length)
length = p.Length;
if ( refin != 0 )
{
crc = reflect(crc, order);
}
if ( refin == 0 )
{
for ( int i = offset; i < length; i++ )
{
crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^ p[i]];
}
}
else
{
for ( int i = offset; i < length; i++ )
{
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 = 0; i < p.Length; i++ )
{
crc = ((crc << 8) | p[i]) ^ crctab[ (crc >> (order-8)) & 0xff ];
}
}
else
{
for ( int i = 0; i < p.Length; i++ )
{
crc = (ulong)(( (int)(crc >> 8) | (p[i] << (order-8))) ^ (int)crctab[ crc & 0xff ]);
}
}
if ( refin == 0 )
{
for ( int i = 0; i < order/8; i++ )
{
crc = (crc << 8) ^ crctab[ (crc >> (order-8)) & 0xff];
}
}
else
{
for ( int i = 0; i < order/8; i++ )
{
crc = (crc >> 8) ^ crctab[crc & 0xff];
}
}
if ( (refout^refin) != 0 )
{
crc = reflect(crc, order);
}
crc^= crcxor;
crc&= crcmask;
return(crc);
}
// Works like crctable(byte[] p), except you now calculate a CRC for a specific part of the byte array.
public ulong crctable (byte[] p, int offset, int length)
{
// normal lookup table algorithm with augmented zero bytes.
// only usable with polynom orders of 8, 16, 24 or 32.
ulong crc = crcinit_nondirect;
if (offset < 0)
offset = 0;
length += offset;
if (length > p.Length)
length = p.Length;
if ( refin != 0 )
{
crc = reflect(crc, order);
}
if ( refin == 0 )
{
for ( int i = offset; i < length; i++ )
{
crc = ((crc << 8) | p[i]) ^ crctab[ (crc >> (order-8)) & 0xff ];
}
}
else
{
for ( int i = offset; i < length; i++ )
{
crc = (ulong)(( (int)(crc >> 8) | (p[i] << (order-8))) ^ (int)crctab[ crc & 0xff ]);
}
}
if ( refin == 0 )
{
for ( int i = 0; i < order/8; i++ )
{
crc = (crc << 8) ^ crctab[ (crc >> (order-8)) & 0xff];
}
}
else
{
for ( int i = 0; i < order/8; i++ )
{
crc = (crc >> 8) ^ crctab[crc & 0xff];
}
}
if ( (refout^refin) != 0 )
{
crc = reflect(crc, order);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?