WORD gen_crc(BYTE far *frame, short frame_len) { BYTE c, treat, bcrc; WORD wcrc = 0; short i, j; for (i = 0; i < frame_len; i++) { c = frame[i]; for (j = 0; j < 8; j++) { treat = c & 0x80; c <<= 1; bcrc = (wcrc >> 8) & 0x80; wcrc <<= 1; if (treat != bcrc) wcrc ^= 0x1021; } } return wcrc; }
{
BYTE c, treat, bcrc;
WORD wcrc = 0;
short i, j; for (i = 0; i < frame_len; i++)
{
c = frame[i]; for (j = 0; j < 8; j++)
{
treat = c & 0x80;
c <<= 1;
bcrc = (wcrc >> 8) & 0x80;
wcrc <<= 1;
if (treat != bcrc)
wcrc ^= 0x1021;
}
} return wcrc;
}
头文件<CRC.h>
#include <cassert>
#include <iostream>
#include <string>class Crc
{
public:
typedef unsigned long Type; Crc (Type key)
: _key (key), _register (0)
{}
Type Done ()//返回结果
{
Type tmp = _register;
_register = 0;
return tmp;
}
protected:
Type _key; // 储存生成多项式,实际值为33bit,默认下最高位为1
Type _register; // 寄存器,用于存放运算中间结果
};class MyCrc: public Crc
{
public:
MyCrc (Crc::Type key)
: Crc (key)
{}
void PutByte (unsigned char byte);
private:
void PutBit (bool bit);
};void MyCrc::PutByte (unsigned char byte)
{
unsigned char mask = 0x80; // 设置掩膜,最高位,也就是最左边的位为1
for (int j = 0; j < 8; ++j)
{
PutBit ((byte & mask) != 0);
mask >>= 1;
}
}
void MyCrc::PutBit (bool bit)
{
std::cout << bit? "1": "0";// 输出当前处理位信息 bool topBit = (_register & 0x80000000) != 0;
// 将寄存大左移一位
_register <<= 1;
_register ^= (bit? 0x1: 0x0); // 补上传进来的最后一位
if (topBit)// 如果最高位为1的话进行除法运算
{
// 对数据做除法运算,也就是对寄存器用生成多项式做异或运算
// 默认下最高位为1,实际上是33位生成多项式
_register ^= _key;
}
}
调用<crc.cpp>
#include "CRC.h"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
string convertData(string fileName);
int main ()
{
Crc::Type const ethernetKey = 0x04c11db7;//以太网帧中用来算CRC的生成多项式
MyCrc MyCrc (ethernetKey);
string filename;//用于存放进行CRC验证的字符串所在的文件名
//calculate R in: M (x) * x^32 = Q (x) * K (x) + R (x)
cout<<"请输入你要进行CRC验证的字符串所在的文件:";
cin>>filename;
string msg=convertData(filename);
size_t origLen = msg.length ();
// 为要进行CRC计算的多项式补上32位0
msg.resize (origLen + sizeof (Crc::Type));
//进行CRC计算
for (size_t i = 0; i < msg.length (); ++i)
{
std::cout << " ";
MyCrc.PutByte (msg [i]);
}
std::cout << "\n<- ";
Crc::Type crc = MyCrc.Done ();// 返回计算结果
std::cout << "\n0x" << std::hex << crc << std::endl; //以十六进制的方式输出计算结果 // 测试CRC验证码。 // 为要进行验证的字符串在后面补上CRC验证码
int shift = 32;
for (int j = 0; j < sizeof (MyCrc::Type); ++j)
{
shift -= 8;
msg [origLen + j]
= static_cast<unsigned char> (crc >> shift);
} // 进行验证,应该可以被CRC生成多项式整除
for (size_t i = 0; i < msg.length (); ++i)
{
std::cout << " ";
MyCrc.PutByte (msg [i]);
}
std::cout << "\n<- ";
crc = MyCrc.Done ();
std::cout << "\n0x" << std::hex << crc << std::endl;
assert (crc == 0);//断言整除生成多项式
system("pause");
return 0;
}string convertData(string fileName)
{
unsigned short iTemp;
ostringstream ostrstream("");
try{
ifstream inputFile(fileName.c_str());
while(inputFile.good() && !inputFile.eof())
{
inputFile>>hex>>iTemp;
ostrstream<<static_cast<char>(iTemp);
}
}
catch(...)
{
cout<<"something is wrong";
}
return ostrstream.str();
}