⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framer.cpp

📁 计算crc校验码的程序
💻 CPP
字号:
/*! \file framer.cpp : 
    \brief 定义控制台应用程序的入口点。
*/


#include "stdafx.h"
#include "framer.h"
using namespace std;

/*! \fn bool frameheader(char* outfile,char* tempfile)
    \brief 形成帧的前导码、帧定界符、目的地址和源地址,输出到输出文件。
    \param  char* outfile 为输出文件名
	\param  char* tempfile 临时文件名
    \returns 输出成功,则返回为真
*/

bool frameheader(char* outfile,char* tempfile)                      
{
	
	  //数组存放7字节前导码、1字节帧定界符、6字节目的地址和6字节源地址。
	    
	   
	unsigned char head[8]={0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAB};// 7字节前导码,每字节均为10101010,帧前导码10101011;
	unsigned char add[12]={0x00,0x00,0xE4,0x86,0x3A,0xDC,         //目标地址00-00-E4-86-3A-DC;
						   0x00,0x00,0x80,0x1A,0xE6,0x65};        //源地址00-00-80-1A-E6-65
							
   ofstream tfile( tempfile );
   ofstream ofile( outfile );
   tfile.write( (char *) &head, sizeof head );
   tfile.write( (char *) &add, sizeof add);
   ofile.write( (char *) &head, sizeof head );
   tfile.close();
  ofile.close();
   return true;
}
/*! \fn bool length(char* infile,char* tempfile)
    \brief 将输入文件的字节长度文件数据输出到临时文件,不足46字节的以0补齐。
    \param char* infile 输入文件名
    \param char* tempfile 临时文件名
    \returns 输出成功,则返回为真
 */

bool length(char* infile,char* tempfile)
{

	ifstream ifile(infile,ios::binary);
	ofstream tfile( tempfile,ios_base::binary|ios::app );

	if(!ifile)                                        //输入文件无法打开,返回失败。
	{
		cout<<"cannot open"<<infile<<endl;
		return false;
	}
	
	                        
	
	char tempchar;
	unsigned short c1,c2,bytecnt ;

	
	ifile.seekg( 0, ios_base::end );                  //找到二进制文件尾
	c1=c2=bytecnt= ifile.tellg();                     //数据字段长度计数器。
	
	unsigned char b1=c1&0x00ff;                       //将数据长度字段输出到临时文件
	c2>>=8;
    unsigned char b2=c2;
	tfile.put(b2);
    tfile.put(b1);
	
	ifile.seekg(0);                                   //开始读取数据,并输出到临时文件
	int cnt=bytecnt;
	ifile.get(tempchar);
	
	while(cnt>0)
	{
		                 
		cnt--;
		tfile.put(tempchar);
		ifile.get(tempchar);
	}
	
	
	if(bytecnt>46)                                    //数据字段大于46字节,成功返回
	{
		tfile.close();
		ifile.close();
		return true;
	}
	
	tempchar=0;
	for(int i=bytecnt;i<46;i++)                      //数据字段不足46字节,先用0补足46字节再返回;
		tfile.put(tempchar);
	

	tfile.close();
	ifile.close();
	return true;
}
/*! \fn bool crc(char* tempfile,char* outfile)
    \brief 根据临时文件计算crc校验码,并把计算结果和临时文件的数据输出到输出文件。
	\param char* tempfile 临时文件名
	\param char* outfile 输出文件名
	\returns 输出成功,则返回真。
	
	*/
bool crc(char* tempfile,char* outfile)              
{
	unsigned char crc = 0x00;                       //crc校验码值(寄存器),初始化为0。
	unsigned char gx = 0x07;                        //对应于G(x)=x8+x2+x1+x0
	unsigned char oput = 0;                         //每次左移时,移出的一位
    unsigned char temp;
	unsigned char otemp;
	
	ifstream tfile(tempfile,ios::binary);
	if(!tfile)                                      //临时文件无法打开,返回失败
	{
		cout<<"cannot open file";
		return false;
	}
    
	tfile.seekg(0,ios_base::end);                  //寻找临时文件尾
	int cnt=tfile.tellg();                         //获得临时文件长
	cnt=cnt-7;                                     //7字节前导码、1字节帧定界符不用于计算crc但还要加上crc位本身
	int cnt2=cnt;
	tfile.seekg(8);                                //从第9位开始读取
	
	ofstream ofile( outfile,ios::app|ios_base::binary );
	
	tfile.read((char*)&otemp,sizeof (unsigned char));
	while(cnt>0)                                    //每次从临时文件中读取一字节,计算,然后写到输出文件
	{  
		
		cnt=cnt-1;
		if(cnt!=0)                                 //非crc位
			
		{
			temp=otemp;
			ofile.put(otemp);
		}
		else
			temp=0;                                //cnt=0即为crc位,crc位为0
		
		
		int i=0;
		while(i<8)                                    //对每一位入寄存器计算
		{
			oput = crc & 0x80;                       //取上次计算crc的最高位,此次左移即为输出位;
			crc <<= 1;                               //寄存器左移一位
			if (temp & 0x80)                         //每次取字节的最高位,作为输入,判断是否为0
			{                           
				crc |= 0x01;                         //非0,则将crc最低位与1取或,即最低为取一,其它位不变,即将1移入
				                                     //寄存器,若为0,则无需变化
			} 	
			temp <<= 1;

			if ( oput )                              //若输出位为1,则将crc与gx对应位取异或,
				                                     //若为0,取异或结果不变,无需计算  
			{
				crc ^= gx; 
			}
			i=i+1;
		}
		
		tfile.read((char*)&otemp,sizeof (unsigned char));
	}
	
	ofile.put(crc);                               //输出校验和数据
	ofile.close();
	tfile.close();
	return true;
}





int _tmain(int argc, _TCHAR* argv[])
{
	if(argc!=3)                                   //输入命令行参数不合要求,返回失败
	{
		cout<<"USAGE:framer inputfile outputfile"<<endl;
		cout<<"inputfile name:input1 || input2"<<endl;
		return 1;
	}

                                                                  

	_TCHAR tname[20];                         //生成临时文件的名字 t+输出文件名 
	tname[0]='t';
	for(int j=0;argv[2][j]!='\0';j++)
		tname[j+1]=argv[2][j];
	tname[j+1]='\0';

	
	if(frameheader(argv[2],tname))                //生成帧头部的前导码、帧定界符、目的地址和源地址,输出到输出文件
		cout<<"frame header formed"<<endl;
	else                                          //失败则返回
	{
		cout<<"frame header form failed"<<endl;
		return 1;
	}
	if(length(argv[1],tname))             //将输入文件的字节长度、文件数据输出到临时文件,不足46字节的以0补齐。
		cout<<"data length count finished"<<endl;
	else
	{
		cout<<"data length count failed"<<endl;
		return 1;
	}
	if(crc(tname,argv[2]))                         //根据临时文件计算crc校验码,并把计算结果和临时文件的数据输出到输出文件。
		cout<<"crc finished"<<endl;
	else
	{
		cout<<"crc failed"<<endl;
		return 1;
	}

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -