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

📄 iso8583.c

📁 通过配置化实现的8583打包以及解包函数
💻 C
📖 第 1 页 / 共 2 页
字号:
		else if ( DataBuffer[0] == '0' )
			DataBuffer[0] = 'C';
}

/*===========================================================================*/
/* Local Function - Convert Data From Data Buffer                            */
/*---------------------------------------------------------------------------*/
static	void	CvtDatFromDataBuffer( ISO8583FLDDAT *Dat, ISO8583FLDDEF *Fld )
{
	if ( BufDatSize > 0 && Fld->Type == FT_AMT )
		if ( DataBuffer[0] == 'D' )
			DataBuffer[0] = '-';
		else if ( DataBuffer[0] == 'C' )
			DataBuffer[0] = '0';

	switch ( Dat->Type ) {
	case DT_CHAR:
		memset( Dat->Data, 0, Dat->Size );
		if ( BufDatSize > Dat->Size )
			BufDatSize = Dat->Size;
		memcpy( Dat->Data, DataBuffer, BufDatSize );
		Dat->Size = BufDatSize;
		break;

	case DT_STRING:
		memset( Dat->Data, 0, Dat->Size );
		if ( BufDatSize >= Dat->Size )
			BufDatSize = Dat->Size - 1;
		DataBuffer[BufDatSize] = 0;
		memcpy( Dat->Data, DataBuffer, BufDatSize );
		break;

	case DT_BYTE:
		*((char *) Dat->Data) = atoi( DataBuffer );
		break;

	case DT_UBYTE:
		*((unsigned char *) Dat->Data) = atoi( DataBuffer );
		break;

	case DT_SHORT:
		*((short *) Dat->Data) = atoi( DataBuffer );
		break;

	case DT_USHORT:
		*((unsigned short *) Dat->Data) = atoi( DataBuffer );
		break;

	case DT_LONG:
		*((long *) Dat->Data) = atol( DataBuffer );
		break;

	case DT_ULONG:
		*((unsigned long *) Dat->Data) = atol( DataBuffer );
		break;

	case DT_FLOAT:
		*((float *) Dat->Data) = atof( DataBuffer );
		break;

	case DT_DOUBLE:
		*((double *) Dat->Data) = atof( DataBuffer );
		break;
	}
}

/*===========================================================================*/
/* Local Function - MAC Add Field                                            */
/*---------------------------------------------------------------------------*/
static	int	MACAddField( int FNo, char *Buf, unsigned int Size )
{
	int	t;
	unsigned int	r, w;
	ISO8583FLDDEF	*Def = FldDef + FNo;
	ISO8583FLDDAT	*Dat = FldDat + FNo;

	if ( Dat->Type == DT_NONE )
		return 0;
	t = CheckFieldType( Def->Type );
	if ( FldTypeLst[t].MACPck == NULL )
		return -1;
	CvtDatToDataBuffer( Dat, Def );
	r = BufDatSize;
	w = Size;
	if ( ( *FldTypeLst[t].MACPck )( Def->Fmt, Def->Type, Def->Len,
			DataBuffer, &r, Buf, &w ) != 0 )
		return -1;
	return (int) w;
}

/*===========================================================================*/
/* Local Function - Pack Field                                               */
/*---------------------------------------------------------------------------*/
static	int	PackField( int FNo, char *Buf, unsigned int Size )
{
	int	t;
	unsigned int	r, w;
	ISO8583FLDDEF	*Def = FldDef + FNo;
	ISO8583FLDDAT	*Dat = FldDat + FNo;

	t = CheckFieldType( Def->Type );
	if ( FldTypeLst[t].Pack == NULL )
		return -1;
	CvtDatToDataBuffer( Dat, Def );
	r = BufDatSize;
	w = Size;
	if ( ( *FldTypeLst[t].Pack )( Def->Fmt, Def->Type, Def->Len,
			DataBuffer, &r, Buf, &w ) != 0 )
		return -1;
	return (int) w;
}

/*===========================================================================*/
/* Local Function - Unpack Field                                             */
/*---------------------------------------------------------------------------*/
static	int	UnpackField( int FNo, const char *Buf, unsigned int Size )
{
	int	t;
	unsigned int	r, w;
	ISO8583FLDDEF	*Def = FldDef + FNo;
	ISO8583FLDDAT	*Dat = FldDat + FNo;
	t = CheckFieldType( Def->Type );
	if ( FldTypeLst[t].Unpack == NULL )
		return -1;
	
	r = Size;
	w = DATBUFSZ;
	if ( ( *FldTypeLst[t].Unpack )( Def->Fmt, Def->Type, Def->Len,
			Buf, &r, DataBuffer, &w ) != 0 )
	{
		return -1;
	}
	BufDatSize = w;
	if ( Dat->Type != DT_NONE )
		CvtDatFromDataBuffer( Dat, Def );
	return (int) r;
}

/*===========================================================================*/
/* Public Function - Patch                                                   */
/*---------------------------------------------------------------------------*/
int	ISO8583Patch( unsigned char FldType, ISO8583Callback Packer,
		ISO8583Callback Unpacker, ISO8583Callback MACPacker )
{
	int 	i;
	ISO8583TYPE	*p;
	if ( FldType == FT_NONE )
		return ISO8583RC_ARG;
	if ( ( i = CheckFieldType( FldType ) ) == FldTypeCnt ) {
		if ( FldTypeCnt == MAXFTCNT )
			return ISO8583RC_SIZE;
		FldTypeCnt ++;
	}

	p = FldTypeLst + i;
	p->Type = FldType;
	p->Pack = Packer;
	p->Unpack = Unpacker;
	p->MACPck = MACPacker;

	return ISO8583RC_OK;
}

/*===========================================================================*/
/* Public Function - Configure                                               */
/*---------------------------------------------------------------------------*/
int	ISO8583Config( const char *ConfigFile )
{
	ISO8583FLDDEF	*p;
	FILE	*f;
	unsigned int	FNo, FLen;
	unsigned char	FFmt, FType;
	char	Line[CFGBUFSZ];

	InitFlag = 0;
	memcpy( FldDef, FldStd, sizeof( FldStd ) );
	ConfigFlag = 1;

	if ( ConfigFile == NULL )
		return ISO8583RC_OK;

	if ( ( f = fopen( ConfigFile, "r" ) ) == NULL )
		return ISO8583RC_ARG;

	while ( fgets( Line, CFGBUFSZ, f ) != NULL ) {
		StringTrim( Line, Line );
		if ( Line[0] == CFGRMSYM || Line[0] == 0 )
			continue;
		if ( sscanf( Line, "%u %c %c %u", &FNo, &FFmt, &FType, &FLen )
				!= 4 )
			continue;
		if ( CheckFieldNumber( FNo ) < 0 )
			continue;
		if ( FFmt != FF_FIX && FFmt != FF_LL && FFmt != FF_LLL )
			continue;
		if ( CheckFieldType( FType ) == FldTypeCnt )
			continue;
		if ( FLen == 0 || FFmt == FF_LL && FLen > 99
				|| FFmt == FF_LLL && FLen > 999 )
			continue;

		p = FldDef + FNo - 1;
		p->Fmt = FFmt;
		p->Type = FType;
		p->Len = FLen;
	}

	fclose( f );
	return ISO8583RC_OK;
}

/*===========================================================================*/
/* Public Function - Initial                                                 */
/*---------------------------------------------------------------------------*/
void	ISO8583Init()
{
	int	i;
	ISO8583FLDDAT	*p;

	memset( BMP, 0, BMPBYTES );

	for ( i = 0; i < MAXFIELD; i ++ ) {
		p = FldDat + i;
		p->Type = DT_NONE;
		p->Size = 0;
		p->Data = NULL;
	}

	for ( i = 0; i < MAXFIELD; i += SECFIELD ) {
		p = FldDat + i;
		p->Type = DT_CHAR;
		p->Data = BMP + ( i / SECFIELD + 1 ) * BMPBPSEC;
		p->Size = BMPBPSEC;
	}

	InitFlag = 1;
}

/*===========================================================================*/
/* Public Function - Define Field                                            */
/*---------------------------------------------------------------------------*/
int	ISO8583FldDef( unsigned char FieldNum, unsigned char DataType,
		void *DataPtr, unsigned short DataSize )
{
	ISO8583FLDDAT	*p;

	if ( InitFlag == 0 )
		return ISO8583RC_INIT;
	if ( CheckFieldNumber( FieldNum ) < 0 )
	{
		return ISO8583RC_ARG;
	}
	if ( DataPtr == NULL )
		return ISO8583RC_ARG;

	p = FldDat + FieldNum - 1;
	switch ( DataType ) {
	case DT_CHAR:
	case DT_STRING:
	case DT_BYTE:
	case DT_UBYTE:
	case DT_SHORT:
	case DT_USHORT:
	case DT_LONG:
	case DT_ULONG:
	case DT_FLOAT:
	case DT_DOUBLE:
		p->Type = DataType;
		break;
	default:
		return ISO8583RC_ARG;
	}
	p->Data = DataPtr;
	p->Size = DataSize;

	return ISO8583RC_OK;
}

/*===========================================================================*/
/* Public Function - Check Field                                             */
/*---------------------------------------------------------------------------*/
int	ISO8583FldChk( unsigned char FieldNum )
{
	if ( InitFlag == 0 )
		return ISO8583RC_INIT;
	if ( CheckFieldNumber( FieldNum ) < 0 )
		return ISO8583RC_ARG;
	if ( BitGet( BMP, FieldNum - 1 ) == 0 )
		return 0;
	return FldDat[FieldNum - 1].Size;
}

/*===========================================================================*/
/* Public Function - Calculate MAC                                           */
/*---------------------------------------------------------------------------*/
int	ISO8583MAC( char *WorkBuffer, unsigned int BufSize,
			const char Key[MACKEYSZ], char MAC[MACFLDSZ],
			unsigned char FieldNum, ... )
{
	int	r;
	unsigned int	s = 0;
	va_list	ArgLst;

	if ( ConfigFlag == 0 )
		return ISO8583RC_CFG;
	if ( InitFlag == 0 )
		return ISO8583RC_INIT;
	if ( WorkBuffer == NULL || BufSize == 0 || MAC == NULL )
		return ISO8583RC_ARG;

	va_start( ArgLst, FieldNum );
	while ( FieldNum != 0 ) {
		if ( CheckFieldNumber( FieldNum ) < 0 )
			return ISO8583RC_ARG;
		if ( ( r = MACAddField( FieldNum - 1, WorkBuffer + s,
				BufSize - s ) ) < 0 )
			return ISO8583RC_SIZE;
		s += r;
		FieldNum = va_arg( ArgLst, int );
	}
	va_end( ArgLst );

	return ISO8583RC_OK;
}

/*===========================================================================*/
/* Public Function - Pack                                                    */
/*---------------------------------------------------------------------------*/
int	ISO8583Pack( const char MTI[MTISIZE], const char MAC[MACFLDSZ],
			char *OutBuffer, unsigned int BufSize )
{
	int	i, r;
	unsigned int	s = MTISIZE + BMPBPSEC;

	if ( ConfigFlag == 0 )
		return ISO8583RC_CFG;
	if ( InitFlag == 0 )
		return ISO8583RC_INIT;
	if ( MTI == NULL )
		return ISO8583RC_ARG;
	if ( s > BufSize )
		return ISO8583RC_SIZE;

	for ( i = 0; i < MAXFIELD; i ++ ) {
		if ( i % SECFIELD == 0 || i % SECFIELD == SECFIELD - 1 )
			continue;
		if ( FldDat[i].Type == DT_NONE )
			continue;
		BitSet( BMP, i, 1 );
		if ( i >= SECFIELD )
			BitSet( BMP, BMPINDICATOR( i ), 1 );
	}
	if ( MAC != NULL ) {
		for ( i = 0; i < MAXFIELD; i += SECFIELD )
			if ( BitGet( BMP, i ) == 0 )
				break;
		i += SECFIELD - 1;
		BitSet( BMP, i, 1 );
		FldDat[i].Type = DT_CHAR;
		FldDat[i].Data = MAC;
		FldDat[i].Size = MACFLDSZ;
	}

	for ( i = 0; i < MAXFIELD; i ++ ) {
		if ( BitGet( BMP, i ) == 0 )
			continue;
		if ( ( r = PackField( i, OutBuffer + s, BufSize - s ) ) < 0 )
			return ISO8583RC_SIZE;
		s += r;
	}
	memcpy( OutBuffer, MTI, MTISIZE );
	memcpy( OutBuffer + MTISIZE, BMP, BMPBPSEC );

	return s;
}

/*===========================================================================*/
/* Public Function - Unpack                                                  */
/*---------------------------------------------------------------------------*/
int	ISO8583Unpack( char MTI[MTISIZE], char MAC[MACFLDSZ],
			const char *InBuffer, unsigned int BufSize )
{
	int	i, r;
	int	c = 0;
	unsigned int	s = MTISIZE + BMPBPSEC;
	if ( ConfigFlag == 0 )
		return ISO8583RC_CFG;
	if ( InitFlag == 0 )
		return ISO8583RC_INIT;
	if ( BufSize < s )
		return ISO8583RC_SIZE;
	if ( MTI != NULL )
		memcpy( MTI, InBuffer, MTISIZE );

	memcpy( BMP, InBuffer + MTISIZE, BMPBPSEC );

	for ( i = 0; i < MAXFIELD; i ++ ) {
		if ( i % SECFIELD == SECFIELD - 1 )
			continue;

		if ( BitGet( BMP, i ) == 0 )
			continue;
			
		if ( ( r = UnpackField( i, InBuffer + s, BufSize - s ) ) < 0 )
		{
			return ISO8583RC_SIZE;
		}
		s += r;
		if ( r > 0 )
			c ++;
	}

	for ( i = 0; i < MAXFIELD; i += SECFIELD )
		if ( BitGet( BMP, i ) == 0 )
			break;
/*********************
//modify 0806 for 2641
	if ( BitGet( BMP, i + SECFIELD - 1 ) == 1 ) {
		if ( BufSize < s + MACFLDSZ ){
		return ISO8583RC_SIZE;}
		BufSize -= MACFLDSZ;
		if ( MAC != NULL )
			memcpy( MAC, InBuffer + BufSize, MACFLDSZ );
	}

	if ( s != BufSize )
		return ISO8583RC_SIZE;

***************/
	return c;
}

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

⌨️ 快捷键说明

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