FSN文件的解析(点钞机读取钱币文件)

1、FsnParser.h文件

#pragma once
#include <Windows.h>
#include <iostream>
#include <vector>
#include <fstream>




#define READ_SIZE 100
/**
* @brief 单个图像结构
*/
typedef struct
{
	unsigned int Data[32];		/**< 图像冠字号点阵数据 */
}BOC_BOC_TImageSNoData;


/**
* @brief 图像冠字号码结构
*/
typedef struct
{
	short Num;				/**< 字符数 */
	short Height, width;	/**< 每个图像字符高度和宽度 */
	short Reserve2;			/**< 保留字2 */
	BOC_BOC_TImageSNoData SNo[12];
}BOC_TImageSNo;

typedef struct
{
	USHORT HeadStart[4];
	USHORT HeadString[6];
	UINT Counter;
	USHORT HeadEnd[4];
}BOC_Header_Fromat;

/**
* @brief 文件记录结构
*/
typedef struct
{
	USHORT Date;			/**< 验钞启动日期 Date=((Year-1980)<<9)+(Month<<5)+Day*/   //
	USHORT Time;			/**< 验钞启动时间 Time=(Hour<<11)+(Minute<<5)+(Second>>1)*/
	USHORT tfFlag;			/**< 真、假、残和旧币标志 */					 //
	USHORT ErrorCode[3];	/**< 错误码(3个) */
	USHORT MoneyFlag[4];	/**< 货币标志 */								 //
	USHORT Ver;				/**< 版本号 */
	USHORT Valuta;			/**< 币值 */									//				
	USHORT CharNUM;			/**< 冠字号码字符数 */
	USHORT SNo[12];			/**< 冠字号码 */                               //
	USHORT MachineSNo[24];	/**< 机具编号 */
	USHORT Operateor_No;		/**< 保留字1 */
}BOC_TagData_Fromat;


typedef  struct {   //为变长类型
	UINT  u32_ImgDataLen;  //图片文件长度
	UINT  u32_Image_Width;//图像宽度
	UINT  u32_Image_Height;//图像高度
	UCHAR   u8_Filetype[8];//文件类型.jpg  或者 .bmp  
	UCHAR   Reserve[60];  //空出60个字节
}TKTImageSNo_File;
//u32_ImgDataLen
//图片数据

typedef  struct {
	USHORT  u16_Date;
	USHORT  u16_Time;
	USHORT  u16_tfFlag;
	USHORT  u16_ErrorCode[3];
	USHORT  u16_MoneyFlag[4];
	USHORT  u16_Ver;
	USHORT  u16_Valuta;
	USHORT  u16_CharNum;
	USHORT  u16_SNo[12];
	USHORT  u16_MachineSNo[24];
	USHORT  u16_Reservel[20];  //空出40个字节
							   //TKTImageSNo_File  ImageSNo_File;
}TKFSN_Record_File;

//2015-10号文,保留字的组成
typedef struct
{
	USHORT machineSNo_Length : 4;
	USHORT machine_Length : 4;
	USHORT machine_Type : 4;
	USHORT money_Type : 4;
}FSN_Reserve, *PFSN_Reserve;

#pragma pack()

enum ImageType
{
	FSN_IMG_Standard = 0xC0,
	FSN_IMG_JPG,
};


typedef struct
{
	BOC_TagData_Fromat btf;
	USHORT uFileFlag;		//文件索引
	DWORD  dwOffset;		//文件图片索引
	CHAR   bSame;			//是否合格
	INT	   llLen;			//图片文件长度
	BYTE   uFileType;		//文件类型
	int    nImgWidth;
	int    nImgHeight;
}BOC_TagRecord_Data;

struct Money_Info
{
	std::string Id;
	std::string Value;
	std::string Kinds;
	std::string IsReal;
	std::string time;
	std::string CharNum;
	std::string MachineSNo;
};
using namespace std;
class FsnParser
{
public:
	std::vector<Money_Info> ReadTk(std::string &filename,int ncount);
	Money_Info  InsList(vector<BOC_TagRecord_Data*>& vecRecord, int nStartPos);
	vector<BOC_TagRecord_Data*> m_vecRecordData;
private:
	vector<Money_Info> m_vecMoneyInfo;
};


2、FsnParser.cpp文件

#define _CRT_SECURE_NO_WARNINGS
#include "FSN_Parser.h"
#include <iostream>
#include <stdio.h>





void* __cdecl memcpy(void* dst,const void* src,size_t count)
{
	void*ret = dst;
#if defined(_M_MRX000)||defined(_M_ALPHA)||defined(_M_PPC)
	{
		extern void RtlMoveMemory(void *, const void *, size_t count);
		RtlMoveMemory(dst, src, count);
	}
#else
	while (count--) {
		*(char *)dst = *(char *)src;
		dst = (char *)dst + 1;
		src = (char *)src + 1;
	}
#endif 
	return (ret);
}
//解析FSN文件
//BOC_TagData_Fromat *btf = (BOC_TagData_Fromat*)malloc(sizeof(BOC_TagData_Fromat*));
//int len = sizeof(BOC_TagData_Fromat*);
std::vector<Money_Info> FsnParser::ReadTk(std::string &filename,int ncount)
{
	FILE *myf = fopen(filename.c_str(), "rb");
	if (myf == nullptr)
	{
		cout << "Error opening file"; 
		exit(1);
	}
	char buffer[3072] = { 0 };
	int iread_offset = 0;
	iread_offset += sizeof(BOC_Header_Fromat);
	int read_size = READ_SIZE;							//文件记录
	int position = 0;
	std::vector<Money_Info> Vec_MoneyInfo;
	fseek(myf, 0, 2);
	int fileSize = ftell(myf);                              //求文件的长度
	while (!feof(myf))
	{
		fseek(myf, iread_offset, SEEK_SET);
		position = ftell(myf);
		fread(buffer, read_size, 1, myf);
		iread_offset += READ_SIZE;
		TKFSN_Record_File *pdata = (TKFSN_Record_File*)buffer;
		BOC_TagRecord_Data *bctd = new BOC_TagRecord_Data;				//数据标记记录
		memset(bctd, 0, sizeof(BOC_TagRecord_Data));
		bctd->btf.Date = pdata->u16_Date;
		bctd->btf.Time = pdata->u16_Time;
		bctd->btf.tfFlag = pdata->u16_tfFlag;
		memcpy(bctd->btf.ErrorCode, pdata->u16_ErrorCode, sizeof(bctd->btf.ErrorCode));
		memcpy(bctd->btf.MoneyFlag, pdata->u16_MoneyFlag, sizeof(bctd->btf.MoneyFlag));
		bctd->btf.CharNUM = pdata->u16_CharNum;
		memcpy(bctd->btf.SNo, pdata->u16_SNo, sizeof(bctd->btf.SNo));
		memcpy(bctd->btf.MachineSNo, pdata->u16_MachineSNo, sizeof(bctd->btf.MachineSNo));
		iread_offset += sizeof(BOC_TImageSNo);
		m_vecRecordData.push_back(bctd);
		ncount++;
		Money_Info m_info = InsList(m_vecRecordData, ncount-1);
		Vec_MoneyInfo.push_back(m_info);
	}	
	fclose(myf);
	return Vec_MoneyInfo;
}
Money_Info  FsnParser::InsList(vector<BOC_TagRecord_Data*>& vecRecord, int nStartPos)
{
	int j = 0;
	unsigned char idLevel = 0;
	int nEndPos = vecRecord.size();
	Money_Info m_info;												//保存Money信息的数据结构
	for (int i = nStartPos; i < nEndPos; i++)
	{
		BOC_TagData_Fromat* pdata = &vecRecord[i]->btf;
		char tmpbuf[26];
		//SNo
		memset(tmpbuf, 0, 26);
		for (j = 0; j < 12; j++)
		{
			tmpbuf[j] = pdata->SNo[j] & 0xFF;
			std::cout << tmpbuf[j] << "    ";
		}
		m_info.Id = tmpbuf;//
		//CharNum
		memset(tmpbuf, 0, 26);
		sprintf_s(tmpbuf, "%d", pdata->CharNUM);
		m_info.CharNum = tmpbuf;//
		//面值
		memset(tmpbuf, 0, 26);
		sprintf_s(tmpbuf, "%d", pdata->Valuta);
		m_info.Value = tmpbuf; //
		//MomeyId 币种
		memset(tmpbuf, 0, 26);
		for (j = 0; j < 4; j++)
		{
			tmpbuf[j] = pdata->MoneyFlag[j] & 0xFF;
		}
		m_info.Kinds = tmpbuf; //
		//真伪
		memset(tmpbuf, 0, 26);
		sprintf_s(tmpbuf, "%d", pdata->tfFlag);
		m_info.IsReal = tmpbuf;
		//错误码
		memset(tmpbuf, 0, 26);
		idLevel = (pdata->ErrorCode[1] >> 8);
		//机具编号
		memset(tmpbuf, 0, 26);
		for (j = 0; j < 24; j++)
		{
			tmpbuf[j] = pdata->MachineSNo[j] & 0xFF;
			std::cout << tmpbuf[j];
		}
		m_info.MachineSNo = tmpbuf;//
		//时间戳
		memset(tmpbuf, 0, 26);
		sprintf_s(tmpbuf, "%04d-%02d-%02d %02d:%02d:%02d", (pdata->Date >> 9) + 1980, (pdata->Date >> 5) & 0x0F, pdata->Date & 0x1F,
			(pdata->Time >> 11), (pdata->Time >> 5) & 0x3F, (pdata->Time << 1) & 0x3F);
		m_info.time = tmpbuf;//
		return m_info;
	}
}

3、测试代码

int main()
{
	int rtn = foo(10);
	std::vector<Money_Info> Vec_MoneyInfo;
	FsnParser ftd ;
	std::string path="e:\\095720.FSN";
	Vec_MoneyInfo = ftd.ReadTk(path,0);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值