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

📄 iso8583.c

📁 通过配置化实现的8583打包以及解包函数
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
/*        ISO-8583 Packet / Unpacket Function Library - Internal Data        */
/* ------------------------------------------------------------------------- */
/* Author: Frank Ho <frank_ho@263.net>, March 20, 2002                       */
/*****************************************************************************/

#include	<stdio.h>
#include	<stdlib.h>
#include	<memory.h>
#include	<string.h>
#include	<stdarg.h>
#include	"applib.h"
#include	"iso8583.h"

/*===========================================================================*/
/* ISO8583 Version Definition                                                */
/*---------------------------------------------------------------------------*/
#define	CFGBUFSZ	128			// Line size of config file
#define	CFGRMSYM	'#'			// Remark symbol of config file
#define	MAXFIELD	128			// Maximum field number
#define	SECFIELD	64			// Field count per section
#define	SECCOUNT	( MAXFIELD / SECFIELD )	// Number of sections
#define	BMPBYTES	( MAXFIELD >> 3 )	// Total bitmap bytes
#define	BMPBPSEC	( SECFIELD >> 3 )	// Bitmap bytes per section
#define	MAXFTCNT	16			// Maximum field type count
#define	STDFTCNT	5			// Standard filed type count

/*===========================================================================*/
/* ISO8583 Macro Definition                                                  */
/*---------------------------------------------------------------------------*/
#define	BMPINDICATOR(x)	( ( (x) / SECFIELD - 1 ) * SECFIELD )

/*===========================================================================*/
/* Other Constants Definition                                                */
/*---------------------------------------------------------------------------*/
#define	DATBUFSZ	1024

/*===========================================================================*/
/* Data Structure Definition                                                 */
/*---------------------------------------------------------------------------*/
typedef	struct	{
	unsigned char	Type;	// Field Type
	ISO8583Callback	Pack;	// Field Packer
	ISO8583Callback	Unpack;	// Field Unpacker
	ISO8583Callback	MACPck;	// Field MAC Packer
}	ISO8583TYPE;
typedef	struct	{
	unsigned char	Fmt;	// Field Format, use FF_*
	unsigned char	Type;	// Field Type, use FT_*
	unsigned short	Len;	// Length of Fixed or Max. Len. of Var. data
}	ISO8583FLDDEF;
typedef	struct	{
	unsigned char	Type;	// Data Type, use DT_*
	unsigned short	Size;	// Data/Buffer Size of DT_CHAR or DT_STRING
	void		*Data;	// Data Pointer
}	ISO8583FLDDAT;

/*===========================================================================*/
/* Field Definition List                                                     */
/*---------------------------------------------------------------------------*/
static	ISO8583FLDDEF	FldStd[] = {
	{ FF_FIX,  FT_BIN,    8 }, //   1: sencondary bitmap
	{ FF_LL,   FT_NUM,   19 }, //   2: primary account number (PAN)
	{ FF_FIX,  FT_NUM,    6 }, //   3: processing code
	{ FF_FIX,  FT_AMT,   12 }, //   4: amount, transaction
	{ FF_FIX,  FT_AMT,   12 }, //   5: amount, settlement
	{ FF_FIX,  FT_AMT,   12 }, //   6: amount, cardholder billing
	{ FF_FIX,  FT_NUM,   10 }, //   7: transmission date and time (GMT)
	{ FF_FIX,  FT_AMT,    8 }, //   8: amount, cardholder billing fee
	{ FF_FIX,  FT_NUM,    8 }, //   9: conversion rate, settlement
	{ FF_FIX,  FT_NUM,    8 }, //  10: conversion rate, cardholder billing
	{ FF_FIX,  FT_NUM,    6 }, //  11: system trace audit number
	{ FF_FIX,  FT_NUM,    6 }, //  12: time, local transaction
	{ FF_FIX,  FT_NUM,    4 }, //  13: date, local transaction
	{ FF_FIX,  FT_NUM,    4 }, //  14: date, expiration
	{ FF_FIX,  FT_NUM,    4 }, //  15: date, settlement
	{ FF_FIX,  FT_NUM,    4 }, //  16: date, conversion
	{ FF_FIX,  FT_NUM,    4 }, //  17: date, capture
	{ FF_FIX,  FT_NUM,    4 }, //  18: merchant type
	{ FF_FIX,  FT_NUM,    3 }, //  19: country code, acquiring institution
	{ FF_FIX,  FT_NUM,    3 }, //  20: country code, PAN extended
	{ FF_FIX,  FT_NUM,    3 }, //  21: country code, forwarding institution
	{ FF_FIX,  FT_NUM,    3 }, //  22: point of service entry mode
	{ FF_FIX,  FT_NUM,    3 }, //  23: application PAN number
	{ FF_FIX,  FT_NUM,    3 }, //  24: network international identifier
	{ FF_FIX,  FT_NUM,    2 }, //  25: point of service condition code
	{ FF_FIX,  FT_NUM,    2 }, //  26: point of service PIN capture code
	{ FF_FIX,  FT_NUM,    1 }, //  27: authorizing Id response length
	{ FF_FIX,  FT_AMT,    8 }, //  28: amount, transaction fee
	{ FF_FIX,  FT_AMT,    8 }, //  29: amount, settlement fee
	{ FF_FIX,  FT_AMT,    8 }, //  30: amount, transaction processing fee
	{ FF_FIX,  FT_AMT,    8 }, //  31: amount, settlement processing fee
	{ FF_LL,   FT_NUM,   11 }, //  32: acquiring institution Id code
	{ FF_LL,   FT_NUM,   11 }, //  33: forwarding institution Id code
	{ FF_LL,   FT_NUM,   28 }, //  34: primary account number, extended
	{ FF_LL,   FT_ANS,   37 }, //  35: track 2 data
	{ FF_LLL,  FT_ANS,  104 }, //  36: track 3 data
	{ FF_FIX,  FT_ANS,   12 }, //  37: retrieval reference number
	{ FF_FIX,  FT_ANS,    6 }, //  38: authorization Id response
	{ FF_FIX,  FT_ANS,    2 }, //  39: response code
	{ FF_FIX,  FT_ANS,    3 }, //  40: service restriction code
	{ FF_FIX,  FT_ANS,    8 }, //  41: card acceptor terminal Id
	{ FF_FIX,  FT_ANS,   15 }, //  42: card acceptor Id code
	{ FF_FIX,  FT_ANS,   40 }, //  43: card acceptor name/location
	{ FF_LL,   FT_ANS,   25 }, //  44: additional response data
	{ FF_LL,   FT_ANS,   76 }, //  45: track 1 data
	{ FF_LLL,  FT_ANS,  999 }, //  46: additional data, ISO
	{ FF_LLL,  FT_ANS,  999 }, //  47: additional data, national
	{ FF_LLL,  FT_ANS,  999 }, //  48: additional data, private
	{ FF_FIX,  FT_ANS,    3 }, //  49: currency code, transaction
	{ FF_FIX,  FT_ANS,    3 }, //  50: currency code, settlement
	{ FF_FIX,  FT_ANS,    3 }, //  51: currency code, cardholder billing
	{ FF_FIX,  FT_BIN,    8 }, //  52: personal Id number (PIN) data
	{ FF_FIX,  FT_NUM,   18 }, //  53: security related control information
	{ FF_LLL,  FT_ANS,  120 }, //  54: additional amounts
	{ FF_NONE, FT_NONE,   0 }, //  55: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, //  56: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, //  57: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, //  58: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, //  59: RESERVED, national
	{ FF_LLL,  FT_ANS,  999 }, //  60: RESERVED, private
	{ FF_LLL,  FT_WKM,  999 }, //  61: RESERVED, private
	//{ FF_LLL,  FT_ANS,  999 }, //  61: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, //  62: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, //  63: RESERVED, private
	{ FF_FIX,  FT_BIN,    8 }, //  64: message authentication code
	{ FF_FIX,  FT_BIN,    8 }, //  65: tertiary bitmap
	{ FF_FIX,  FT_NUM,    1 }, //  66: settlement code
	{ FF_FIX,  FT_NUM,    2 }, //  67: extended payment code
	{ FF_FIX,  FT_NUM,    3 }, //  68: country code, receiving institution
	{ FF_FIX,  FT_NUM,    3 }, //  69: country code, settlement institution
	{ FF_FIX,  FT_NUM,    3 }, //  70: network management information code
	{ FF_FIX,  FT_NUM,    4 }, //  71: message number
	{ FF_FIX,  FT_NUM,    4 }, //  72: message number, last
	{ FF_FIX,  FT_NUM,    6 }, //  73: date, action
	{ FF_FIX,  FT_NUM,   10 }, //  74: credits, number
	{ FF_FIX,  FT_NUM,   10 }, //  75: credits, reversal number
	{ FF_FIX,  FT_NUM,   10 }, //  76: debits, number
	{ FF_FIX,  FT_NUM,   10 }, //  77: debits, reversal number
	{ FF_FIX,  FT_NUM,   10 }, //  78: transfer, number
	{ FF_FIX,  FT_NUM,   10 }, //  79: transfer, reversal number
	{ FF_FIX,  FT_NUM,   10 }, //  80: inquiries, number
	{ FF_FIX,  FT_NUM,   10 }, //  81: authorizations, number
	{ FF_FIX,  FT_AMT,   12 }, //  82: credits, amount, processing fee
	{ FF_FIX,  FT_AMT,   12 }, //  83: credits, amount, transaction fee
	{ FF_FIX,  FT_AMT,   12 }, //  84: debits, amount, processing fee
	{ FF_FIX,  FT_AMT,   12 }, //  85: debits, amount, transaction fee
	{ FF_FIX,  FT_AMT,   15 }, //  86: credits, amount
	{ FF_FIX,  FT_AMT,   15 }, //  87: credits, reversal amount
	{ FF_FIX,  FT_AMT,   15 }, //  88: debits, amount
	{ FF_FIX,  FT_AMT,   15 }, //  89: debits, reversal amount
	{ FF_FIX,  FT_NUM,   42 }, //  90: original data elements
	{ FF_FIX,  FT_ANS,    1 }, //  91: file update code
	{ FF_FIX,  FT_NUM,    2 }, //  92: file security code
	{ FF_FIX,  FT_NUM,    5 }, //  93: response indicatior
	{ FF_FIX,  FT_ANS,    7 }, //  94: service indicator
	{ FF_FIX,  FT_ANS,   42 }, //  95: replacement amounts
	{ FF_FIX,  FT_ANS,    8 }, //  96: message security code
	{ FF_FIX,  FT_AMT,   16 }, //  97: amount, net settlement
	{ FF_FIX,  FT_ANS,   25 }, //  98: payee
	{ FF_LL,   FT_ANS,   11 }, //  99: settlement institution Id code
	{ FF_LL,   FT_NUM,   11 }, // 100: receiving institution Id code
	{ FF_LL,   FT_ANS,   17 }, // 101: file name
	{ FF_LL,   FT_ANS,   28 }, // 102: account Id 1 (from)
	{ FF_LL,   FT_ANS,   28 }, // 103: account Id 2 (to)
	{ FF_LLL,  FT_ANS,  999 }, // 104: transaction description
	{ FF_NONE, FT_NONE,   0 }, // 105: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 106: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 107: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 108: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 109: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 110: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 111: RESERVED, ISO
	{ FF_NONE, FT_NONE,   0 }, // 112: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 113: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 114: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 115: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 116: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 117: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 118: RESERVED, national
	{ FF_NONE, FT_NONE,   0 }, // 119: RESERVED, national
	{ FF_LLL,  FT_ANS,  999 }, // 120: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 121: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 122: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 123: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 124: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 125  RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 126: RESERVED, private
	{ FF_LLL,  FT_ANS,  999 }, // 127: RESERVED, private
	{ FF_FIX,  FT_BIN,    8 }  // 128: message authentication code
};

/*===========================================================================*/
/* Local Function - Standard Field Packer                                    */
/*---------------------------------------------------------------------------*/
static	int	StdFldPacker( unsigned char FldFmt, unsigned char FldType,
			unsigned int FldLen,
			const char *Data, unsigned int *DatSize,
			char *Buffer, unsigned int *BufSize )
{
	unsigned int	s;
	char	t[8];

	switch ( FldFmt ) {
	case FF_FIX:
		if ( *DatSize != FldLen )
			return -1;
		if ( *BufSize < FldLen )
			return -1;
		memcpy( Buffer, Data, FldLen );
		*BufSize = FldLen;
		return 0;

	case FF_LL:
		if ( *DatSize > FldLen )
			return -1;
		s = *DatSize + 2;
		if ( *BufSize < s )
			return -1;
		sprintf( t, "%02u", *DatSize );
		memcpy( Buffer, t, 2 );
		memcpy( Buffer + 2, Data, *DatSize );
		*BufSize = s;
		return 0;

	case FF_LLL:
		if ( *DatSize > FldLen )
			return -1;
		s = *DatSize + 3;
		if ( *BufSize < s )
			return -1;
		sprintf( t, "%03u", *DatSize );
		memcpy( Buffer, t, 3 );
		memcpy( Buffer + 3, Data, *DatSize );
		*BufSize = s;
		return 0;
	}

	return -1;
}

/*===========================================================================*/
/* Local Function - Standard Field Unpacker                                  */
/*---------------------------------------------------------------------------*/
static	int	StdFldUnpacker( unsigned char FldFmt, unsigned char FldType,
			unsigned int FldLen,
			const char *Data, unsigned int *DatSize,
			char *Buffer, unsigned int *BufSize )
{
	unsigned int	s, l;
	char	t[8];

	switch ( FldFmt ) {
	case FF_FIX:
		if ( *DatSize < FldLen )
			return -1;
		if ( *BufSize < FldLen )
			return -1;
		memcpy( Buffer, Data, FldLen );
		*DatSize = FldLen;
		*BufSize = FldLen;
		return 0;

	case FF_LL:
		if ( *DatSize < 2 )
			return -1;
		memcpy( t, Data, 2 );
		t[2] = 0;
		if ( sscanf( t, "%u", &l ) != 1 )
			return -1;
		s = l + 2;
		if ( *DatSize < s )
			return -1;
		if ( *BufSize < l )
			return -1;
		memcpy( Buffer, Data + 2, l );
		*DatSize = s;
		*BufSize = l;
		return 0;

	case FF_LLL:
		if ( *DatSize < 3 )
			return -1;
		memcpy( t, Data, 3 );
		t[3] = 0;
		if ( sscanf( t, "%u", &l ) != 1 )
			return -1;
		s = l + 3;
		if ( *DatSize < s )
			return -1;
		if ( *BufSize < l )
			return -1;
		memcpy( Buffer, Data + 3, l );
		*DatSize = s;
		*BufSize = l;
		return 0;
	}

	return -1;
}

/*===========================================================================*/
/* Field Type Definition List                                                */
/*---------------------------------------------------------------------------*/
static	ISO8583TYPE	FldTypeLst[MAXFTCNT] = {
	{ FT_NONE, NULL,         NULL,           NULL         },
	{ FT_BIN,  StdFldPacker, StdFldUnpacker, StdFldPacker },
	{ FT_ANS,  StdFldPacker, StdFldUnpacker, StdFldPacker },
	{ FT_NUM,  StdFldPacker, StdFldUnpacker, StdFldPacker },
	{ FT_AMT,  StdFldPacker, StdFldUnpacker, StdFldPacker }
};

/*===========================================================================*/
/* Data Definition                                                           */
/*---------------------------------------------------------------------------*/
static	int	ConfigFlag = 0;
static	int	InitFlag = 0;
static	int	FldTypeCnt = STDFTCNT;
static	int	BufDatSize;
static	char	DataBuffer[DATBUFSZ];
static	char	BMP[BMPBYTES];
static	ISO8583FLDDEF	FldDef[MAXFIELD];
static	ISO8583FLDDAT	FldDat[MAXFIELD];

/*===========================================================================*/
/* Local Function - Check Field Type                                         */
/*---------------------------------------------------------------------------*/
static	int	CheckFieldType( unsigned char FldType )
{
	int	i;
	for ( i = 0; i < FldTypeCnt; i ++ )
		if ( FldTypeLst[i].Type == FldType )
			break;
	return i;
}

/*===========================================================================*/
/* Local Function - Check Field Number                                       */
/*---------------------------------------------------------------------------*/
static	int	CheckFieldNumber( unsigned char FieldNum )
{
	if ( FieldNum < 1 || FieldNum > MAXFIELD )
		return -1;
	FieldNum = ( FieldNum - 1 ) % SECFIELD;
	if ( FieldNum == 0 || FieldNum == SECFIELD - 1 )
		return -1;
	return 0;
}

/*===========================================================================*/
/* Local Function - Convert Data To Data Buffer                              */
/*---------------------------------------------------------------------------*/
static	void	CvtDatToDataBuffer( ISO8583FLDDAT *Dat, ISO8583FLDDEF *Fld )
{
	switch ( Dat->Type ) {
	case DT_CHAR:
		if ( Dat->Size < Fld->Len )
			BufDatSize = Dat->Size;
		else
			BufDatSize = Fld->Len;
		memcpy( DataBuffer, Dat->Data, BufDatSize );
		if ( Fld->Fmt == FF_FIX && BufDatSize < Fld->Len ) {
			memset( DataBuffer + BufDatSize, 0,
					Fld->Len - BufDatSize );
			BufDatSize = Fld->Len;
		}
		break;

	case DT_STRING:
		BufDatSize = strlen( Dat->Data );
		if ( BufDatSize > Fld->Len )
			BufDatSize = Fld->Len;
		memcpy( DataBuffer, Dat->Data, BufDatSize );
		if ( Fld->Fmt == FF_FIX && BufDatSize < Fld->Len ) {
			memset( DataBuffer + BufDatSize, ' ',
					Fld->Len - BufDatSize );
			BufDatSize = Fld->Len;
		}
		break;

	case DT_BYTE:
		sprintf( DataBuffer, "%0*d", Fld->Len, (int)
				*((char *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_UBYTE:
		sprintf( DataBuffer, "%0*u", Fld->Len, (unsigned int)
				*((unsigned char *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_SHORT:
		sprintf( DataBuffer, "%0*d", Fld->Len, (int)
				*((short *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_USHORT:
		sprintf( DataBuffer, "%0*u", Fld->Len, (unsigned int)
				*((unsigned short *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_LONG:
		sprintf( DataBuffer, "%0*ld", Fld->Len,
				*((long *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_ULONG:
		sprintf( DataBuffer, "%0*lu", Fld->Len,
				*((unsigned long *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_FLOAT:
		sprintf( DataBuffer, "%0*.0f", Fld->Len,
				*((float *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	case DT_DOUBLE:
		sprintf( DataBuffer, "%0*.0lf", Fld->Len,
				*((double *) Dat->Data) );
		BufDatSize = Fld->Len;
		break;

	default:
		BufDatSize = 0;
	}

	if ( BufDatSize > 0 && Fld->Type == FT_AMT )
		if ( DataBuffer[0] == '-' )
			DataBuffer[0] = 'D';

⌨️ 快捷键说明

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