嵌入式linux之go语言开发(四)go语言8583协议报文解析

时间:2022-07-22
本文章向大家介绍嵌入式linux之go语言开发(四)go语言8583协议报文解析,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原来的pos用c语言开发的,与银联后台通信走的是8583协议。那么用go来做,得实现个go语言8583协议报文解析

且若想在电脑上跑交易,做个工具。用c语音处理起来不方便。用go还可以在电脑上跑交易。

于是用go语言做一个8583解析,方便使用

https://github.com/yangyongzhen/go8583/

package up8583

import (
	"errors"
	"fmt"
	"go8583/byteutil"
	"go8583/desutil"
	"go8583/easy8583"
	"strconv"
)

var (
	ManNum  string = "000000000000000"
	PosNum  string = "00000000"
	MainKey string = "00000000000000000000000000000000"
	TPDU    string = "6000000000"

	CommSn     int    = 1
	RecSn      int    = 1
	PiciNum    []byte = make([]byte, 3)
	LicenceNum        = []byte{0x33, 0x30, 0x36, 0x30}

	MacKey string = "0000000000000000"
)

type Up8583 struct {
	Ea *easy8583.Easy8583
}

func memcpy(dst, src []byte, size int) {
	for i := 0; i < size; i++ {
		dst[i] = src[i]
	}
	return
}

func equals(src1 []byte, src2 []byte) bool {

	if src1 == nil || src2 == nil {
		return false
	}
	le1 := len(src1)
	le2 := len(src2)
	if le1 != le2 {
		return false
	}
	for i := 0; i < le1; i++ {
		if src1[i] != src2[i] {
			return false
		}
	}
	return true
}

/*
银联8583签到组包
*/
func (up *Up8583) Frame8583QD() {

	s := up.Ea
	field := up.Ea.Field_S

	s.Init8583Fields(field)

	//消息类型
	s.Msgtype[0] = 0x08
	s.Msgtype[1] = 0x00

	//11域,受卡方系统跟踪号BCD 通讯流水
	field[10].Ihave = true
	field[10].Len = 3
	sn := fmt.Sprintf("%06d", CommSn)

	field[10].Data = byteutil.HexStringToBytes(sn)

	//41域,终端号
	field[40].Ihave = true
	field[40].Len = 8
	field[40].Data = []byte(PosNum)
	//42域,商户号
	field[41].Ihave = true
	field[41].Len = 15
	field[41].Data = []byte(ManNum)
	//60域
	field[59].Ihave = true
	field[59].Len = 0x11
	field[59].Data = make([]byte, 6)
	field[59].Data[0] = 0x00
	memcpy(field[59].Data[1:], PiciNum, 3)
	field[59].Data[4] = 0x00
	field[59].Data[5] = 0x30
	//62域
	field[61].Ihave = true
	field[61].Len = 0x25
	field[61].Data = make([]byte, 25)
	str := "Sequence No12"
	memcpy(field[61].Data, []byte(str), 13)
	memcpy(field[61].Data[13:], LicenceNum, 4)
	memcpy(field[61].Data[17:], []byte(PosNum), 8)

	//63域
	field[62].Ihave = true
	field[62].Len = 0x03
	field[62].Data = make([]byte, 3)
	field[62].Data[0] = 0x30
	field[62].Data[1] = 0x30
	field[62].Data[2] = 0x31
	/*报文组帧,自动组织这些域到Pack的TxBuffer中*/
	s.Pack8583Fields()

	CommSn++ //通讯流水每次加一

	//s.PrintFields(up.Ea.Field_S)

}

func (up *Up8583) Ans8583QD(rxbuf []byte, rxlen int) error {

	r := up.Ea
	fields := up.Ea.Field_S
	fieldr := up.Ea.Field_R

	ret := r.Ans8583Fields(rxbuf, rxlen)
	if ret == 0 {
		fmt.Println("解析成功")
		r.PrintFields(fieldr)
	} else {
		fmt.Println("解析失败")
		return errors.New("error,failed to ans..")
	}
	//消息类型判断
	if (r.Msgtype[0] != 0x08) || (r.Msgtype[1] != 0x10) {
		//Log.d(TAG,"消息类型错!");
		return errors.New("error,wrong Msgtype ")
	}
	//应答码判断
	if (fieldr[38].Data[0] != 0x30) || (fieldr[38].Data[1] != 0x30) {
		//Log.d(TAG,"应答码不正确!");
		return errors.New("error,wrong resp code:" + fmt.Sprintf("%02x%02x", fieldr[38].Data[0], fieldr[38].Data[1]))
	}
	//跟踪号比较
	//memcmp
	if !equals(fields[10].Data, fieldr[10].Data) {
		return errors.New("error,wrong comm no ")
	}

	//终端号比较
	if !equals(fields[40].Data, fieldr[40].Data) {
		return errors.New("error,posnum not equal ")
	}
	//商户号比较
	if !equals(fields[41].Data, fieldr[41].Data) {
		return errors.New("error,mannum not equal ")
	}
	//3DES解密PIN KEY
	data := make([]byte, 16)
	memcpy(data, fieldr[61].Data, 16)
	pinkey, err := desutil.Des3Decrypt(data, byteutil.HexStringToBytes(MainKey))
	if err != nil {
		return errors.New("1" + err.Error())
	}
	//解密后的结果对8Byte全0做3DES加密运算
	tmp := make([]byte, 8)
	out, err := desutil.Des3Encrypt(tmp, pinkey)
	if err != nil {
		return errors.New("2" + err.Error())
	}
	check := make([]byte, 4)
	pincheck := make([]byte, 4)
	memcpy(check, out, 4)
	memcpy(pincheck, fieldr[61].Data[16:], 4)
	if !equals(check, pincheck) {
		return errors.New("error,Er PIK")
	}
	//3DES解密MAC KEY
	memcpy(data, fieldr[61].Data[20:], 16)
	mackey, err := desutil.Des3Decrypt(data, byteutil.HexStringToBytes(MainKey))
	if err != nil {
		return errors.New("3" + err.Error())
	}
	out, err = desutil.DesEncrypt(tmp, mackey[0:8])
	if err != nil {
		return errors.New("4" + err.Error())
	}
	maccheck := make([]byte, 4)
	memcpy(check, out, 4)
	memcpy(maccheck, fieldr[61].Data[36:], 4)
	if !equals(check, maccheck) {
		return errors.New("error,Er MAC")
	}
	memcpy(PiciNum, fieldr[59].Data[1:], 3)
	MacKey = byteutil.BytesToHexString(mackey[0:8])
	fmt.Printf("mackey:%sn", MacKey)
	up.Ea.SetMacKey(MacKey)
	return nil
}

/*
银联8583 二维码交易组包
*/
func (up *Up8583) Frame8583Qrcode(qrcode string, money int) {

	s := up.Ea
	field := up.Ea.Field_S

	s.Init8583Fields(field)

	//消息类型
	s.Msgtype[0] = 0x02
	s.Msgtype[1] = 0x00

	//3域 交易处理码
	field[2].Ihave = true
	field[2].Len = 3
	field[2].Data = make([]byte, 3)
	//4域 交易金额
	field[3].Ihave = true
	field[3].Len = 6
	field[3].Data = byteutil.HexStringToBytes(fmt.Sprintf("%012d", money))
	//11域,受卡方系统跟踪号BCD 通讯流水
	field[10].Ihave = true
	field[10].Len = 3
	sn := fmt.Sprintf("%06d", RecSn)

	field[10].Data = byteutil.HexStringToBytes(sn)

	//22域
	field[21].Ihave = true
	field[21].Len = 2
	field[21].Data = []byte{0x03, 0x20}
	//25域
	field[24].Ihave = true
	field[24].Len = 1
	field[24].Data = make([]byte, 1)

	//41域,终端号
	field[40].Ihave = true
	field[40].Len = 8
	field[40].Data = []byte(PosNum)
	//42域,商户号
	field[41].Ihave = true
	field[41].Len = 15
	field[41].Data = []byte(ManNum)

	//49域 交易货币代码
	field[48].Ihave = true
	field[48].Len = 3
	field[48].Data = []byte{0x31, 0x35, 0x36}
	//59域,扫码的数据
	field[58].Ihave = true
	field[58].Len = 0x24
	field[58].Data = make([]byte, 24)
	field[58].Data[0] = 'A' //TAG+Len(019)
	field[58].Data[1] = '3'
	field[58].Data[2] = '0'
	field[58].Data[3] = '1'
	field[58].Data[4] = '9'
	memcpy(field[58].Data[5:], []byte(qrcode), 19)

	//60域
	field[59].Ihave = true
	field[59].Len = 0x13
	field[59].Data = make([]byte, 7)
	field[59].Data[0] = 0x22
	memcpy(field[59].Data[1:], PiciNum, 3)
	field[59].Data[4] = 0x00
	field[59].Data[5] = 0x06
	field[59].Data[6] = 0x00

	//MAC,64域
	field[63].Ihave = true
	field[63].Len = 0x08
	field[63].Data = make([]byte, 8)
	//这个域要求填MAC,只需按这样填,MAC的计算在pack8583Fields自动完成了
	/*报文组帧,自动组织这些域到Pack的TxBuffer中*/
	s.Pack8583Fields()

	//CommSn++ //通讯流水每次加一

	//s.PrintFields(up.Ea.Field_S)

}
func NewUp8583() *Up8583 {

	var up = new(Up8583)
	up.Ea = easy8583.New8583()

	up.Ea.Tpdu = byteutil.HexStringToBytes(TPDU)
	return up

}

/*
银联8583 电子现金交易组包
*/
//获取55域 IC卡数据域
/*
9F26 08
9F27 01
9F10
9F37 04
9F36 02
95 05
9A 03
9C 01
9F02 06
5F2A 02
82 02
9F1A 02
9F03 06
9F33 03
9F1E 08
84
9F09 02
9F41 04
9F34 03
9F35 01
9F63 10
9F74 06
8A 02
*/
func getfield55() {

}
func (up *Up8583) Frame8583UpCash(cardbin string, money int, cardvailddata string, cardholdsn string, field55 []byte) {
	s := up.Ea
	field := up.Ea.Field_S

	s.Init8583Fields(field)

	//消息类型
	s.Msgtype[0] = 0x02
	s.Msgtype[1] = 0x00
	//2域 卡号
	field[1].Ihave = true
	tmp := fmt.Sprintf("%02d", len(cardbin))
	t, _ := strconv.ParseInt(tmp, 16, 16)
	if len(cardbin)%2 != 0 {
		cardbin += "0"
	}
	field[1].Len = int(t)
	field[1].Data = byteutil.HexStringToBytes(cardbin)
	//3域 交易处理码
	field[2].Ihave = true
	field[2].Len = 3
	field[2].Data = make([]byte, 3)
	//4域 交易金额
	field[3].Ihave = true
	field[3].Len = 6
	field[3].Data = byteutil.HexStringToBytes(fmt.Sprintf("%012d", money))
	//11域,受卡方系统跟踪号BCD 通讯流水
	field[10].Ihave = true
	field[10].Len = 3
	sn := fmt.Sprintf("%06d", RecSn)

	field[10].Data = byteutil.HexStringToBytes(sn)

	//14域 卡有效期,能获取到时存在
	if len(cardvailddata) > 0 {
		field[13].Ihave = true
		field[13].Len = 2
		field[13].Data = byteutil.HexStringToBytes(cardvailddata)
	}

	//22域
	field[21].Ihave = true
	field[21].Len = 2
	field[21].Data = []byte{0x07, 0x20}
	//23域,卡序列号 能获取时存在
	if len(cardholdsn) > 0 {
		field[22].Ihave = true
		field[22].Len = 2
		field[22].Data = byteutil.HexStringToBytes(cardholdsn)
	}
	//25域
	field[24].Ihave = true
	field[24].Len = 1
	field[24].Data = make([]byte, 1)

	//41域,终端号
	field[40].Ihave = true
	field[40].Len = 8
	field[40].Data = []byte(PosNum)
	//42域,商户号
	field[41].Ihave = true
	field[41].Len = 15
	field[41].Data = []byte(ManNum)

	//49域 交易货币代码
	field[48].Ihave = true
	field[48].Len = 3
	field[48].Data = []byte{0x31, 0x35, 0x36}

	//55域 IC卡数据域
	field[54].Ihave = true
	tmp = fmt.Sprintf("%04d", len(field55))
	b := byteutil.HexStringToBytes(tmp)
	field[54].Len = int(b[0])<<8 | int(b[1])
	field[54].Data = field55
	//60域
	field[59].Ihave = true
	field[59].Len = 0x13
	field[59].Data = make([]byte, 7)
	field[59].Data[0] = 0x36
	memcpy(field[59].Data[1:], PiciNum, 3)
	field[59].Data[4] = 0x00
	field[59].Data[5] = 0x06
	field[59].Data[6] = 0x00
	//63域
	field[62].Ihave = true
	field[62].Len = 0x03
	field[62].Data = make([]byte, 3)
	memcpy(field[62].Data, []byte("CUP"), 3)
	//MAC,64域
	field[63].Ihave = true
	field[63].Len = 0x08
	field[63].Data = make([]byte, 8)
	//这个域要求填MAC,只需按这样填,MAC的计算在pack8583Fields自动完成了
	/*报文组帧,自动组织这些域到Pack的TxBuffer中*/
	s.Pack8583Fields()
}

func (up *Up8583) Ans8583UpCash(rxbuf []byte, rxlen int) error {

	r := up.Ea
	fields := up.Ea.Field_S
	fieldr := up.Ea.Field_R

	ret := r.Ans8583Fields(rxbuf, rxlen)
	if ret == 0 {
		fmt.Println("解析成功")
		r.PrintFields(fieldr)
	} else {
		fmt.Println("解析失败")
		r.PrintFields(fieldr)
		return errors.New("error,failed to ans..")
	}
	//消息类型判断
	if (r.Msgtype[0] != 0x02) || (r.Msgtype[1] != 0x10) {
		//Log.d(TAG,"消息类型错!");
		return errors.New("error,wrong Msgtype ")
	}
	//应答码判断
	if (fieldr[38].Data[0] != 0x30) || (fieldr[38].Data[1] != 0x30) {
		//Log.d(TAG,"应答码不正确!");
		return errors.New("error,wrong resp code:" + fmt.Sprintf("%02x%02x", fieldr[38].Data[0], fieldr[38].Data[1]))
	}
	//跟踪号比较
	//memcmp
	if !equals(fields[10].Data, fieldr[10].Data) {
		return errors.New("error,wrong comm no ")
	}

	//终端号比较
	if !equals(fields[40].Data, fieldr[40].Data) {
		return errors.New("error,posnum not equal ")
	}
	//商户号比较
	if !equals(fields[41].Data, fieldr[41].Data) {
		return errors.New("error,mannum not equal ")
	}
	//MAC验证
	mac, err := easy8583.UpGetMac(rxbuf[13:], rxlen-13-8, easy8583.MacKey)
	if err != nil {
		fmt.Println(err)
		panic("calc mac error!")
	}
	if !equals(fieldr[63].Data, mac) {
		return errors.New("error,mac check err")
	}

	return nil
}
func main() {

	fmt.Println("test...")

	up := NewUp8583()
	//up.Frame8583QD()

	//recvstr := "007960000001386131003111080810003800010AC0001450021122130107200800085500323231333031343931333239303039393939393930363030313433303137303131393939390011000005190030004046F161A743497B32EAC760DF5EA57DF5900ECCE3977731A7EA402DDF0000000000000000CFF1592A"

	//recv := byteutil.HexStringToBytes(recvstr)
	//ret := up.Ea.Ans8583Fields(recv, len(recv))
	//if ret == 0 {
	// 	fmt.Println("解析成功")
	// 	up.Ea.PrintFields(up.Ea.Field_R)
	// } else {
	// 	fmt.Println("解析失败")
	// }

	up.Frame8583QD()
	up.Ea.PrintFields(up.Ea.Field_S)
	//fmt.Println(byteutil.BytesToHexString(up.Ea.Txbuf))
	up.Frame8583Qrcode("6220485073630469936", 1)
	up.Ea.PrintFields(up.Ea.Field_S)

}
/**
 * Created by yangyongzhen on 2019/01/11
 * simple 8583 Protocol Analysis
 */

package easy8583

import (
	"bytes"
	"fmt"
	"strconv"
)

type Field struct {
	Ihave bool   //是否存在该域
	Ltype int    //长度类型 (NOVAR,LLVAR,LLLVAR)
	Dtype int    //数据类型 (BCD,ASCII)
	Len   int    //域的数据内容的长度
	Data  []byte //域的有效数据
}

type Easy8583 struct {
	Len     []byte
	Tpdu    []byte
	Head    []byte
	Msgtype []byte
	Bitmap  []byte

	Txbuf   []byte

	Field_S []Field //发送的域
	Field_R []Field //接收的域
}

//定义枚举类型 长度类型定义
const (
	NOVAR  = iota //value = 0,定长,
	LLVAR         //value = 1,长度为1字节
	LLLVAR        //value = 2,长度为2字节

)

//定义枚举类型 数据类型定义
const (
	UN  = iota //value = 0, 未定义,定长的域无需关注类型
	BIN        //value = 1,BIN
	BCD        //value = 2,BCD
)

//各个域的初始配置
func (ea *Easy8583) Init8583Fields(fds []Field) {

	 for i := 0; i < 64;i++ {
	 	fds[i].Ihave = false
	 }

	fds[0].Ltype = 0

	fds[1].Ltype = LLVAR //LLVAR
	fds[1].Dtype = BCD

	fds[2].Ltype = 0
	fds[2].Len = 3

	fds[3].Ltype = 0
	fds[3].Len = 6

	fds[10].Ltype = 0
	fds[10].Len = 3

	fds[11].Ltype = 0
	fds[11].Len = 3

	fds[12].Ltype = 0
	fds[12].Len = 2

	fds[13].Ltype = 0
	fds[13].Len = 2
	fds[14].Ltype = 0
	fds[14].Len = 2

	fds[21].Ltype = 0
	fds[21].Len = 2
	fds[22].Ltype = 0
	fds[22].Len = 2

	fds[24].Ltype = 0
	fds[24].Len = 1
	fds[25].Ltype = 0
	fds[25].Len = 1

	fds[31].Ltype = LLVAR //LLVAR
	fds[31].Dtype = BCD
	fds[34].Ltype = LLVAR //LLVAR
	fds[34].Dtype = BCD

	fds[36].Ltype = 0
	fds[36].Len = 12

	fds[37].Ltype = 0
	fds[37].Len = 6
	fds[38].Ltype = 0
	fds[38].Len = 2

	fds[39].Ltype = LLVAR

	fds[40].Ltype = 0
	fds[40].Len = 8
	fds[41].Ltype = 0
	fds[41].Len = 15

	fds[43].Ltype = LLVAR

	fds[47].Ltype = LLLVAR
	fds[47].Dtype = BCD

	fds[48].Ltype = 0
	fds[48].Len = 3
	fds[51].Ltype = 0
	fds[51].Len = 8
	fds[52].Ltype = 0
	fds[52].Len = 8

	fds[54].Ltype = LLLVAR //LLLVAR
	fds[58].Ltype = LLLVAR

	fds[59].Ltype = LLLVAR
	fds[59].Dtype = BCD

	fds[60].Ltype = LLLVAR
	fds[60].Dtype = BCD

	fds[61].Ltype = LLLVAR
	fds[62].Ltype = LLLVAR

	fds[63].Ltype = 0
	fds[63].Len = 8

}

/*
构造函数,初始化
*/

func New8583() *Easy8583 {

	var ea = new(Easy8583)
	ea.Txbuf = make([]byte, 0, 1024)
	ea.Txbuf = ea.Txbuf[0:23]

	ea.Len  = []byte{0x00, 0x00}
	ea.Tpdu = []byte{0x60, 0x05, 0x01, 0x00, 0x00}
	ea.Head = []byte{0x61, 0x31, 0x00, 0x31, 0x11, 0x08}

	ea.Msgtype = []byte{0x08, 0x00}

	ea.Bitmap = make([]byte, 8)

	ea.Field_S = make([]Field,64)
	ea.Field_R = make([]Field,64)

	ea.Init8583Fields(ea.Field_S)
	ea.Init8583Fields(ea.Field_R)


	return ea
}

func memcpy(dst, src []byte, size int) {
	for i := 0; i < size; i++ {
		dst[i] = src[i]
	}
	return
}

func bytesToHexStr(data []byte, lenth int) string {
	buf := data[0:lenth]
	hexStr := fmt.Sprintf("%x", buf)
	//fmt.Println(hexStr)
	return hexStr

}

// bytes to hex string
func bytesToHexString(b []byte) string {
	var buf bytes.Buffer
	for _, v := range b {
		t := strconv.FormatInt(int64(v), 16)
		if len(t) > 1 {
			buf.WriteString(t)
		} else {
			buf.WriteString("0" + t)
		}
	}
	return buf.String()
}

// hex string to bytes
func hexStringToBytes(s string) []byte {
	bs := make([]byte, 0)
	for i := 0; i < len(s); i = i + 2 {
		b, _ := strconv.ParseInt(s[i:i+2], 16, 16)
		bs = append(bs, byte(b))
	}
	return bs
}

//例:0x19 --> 19, 0x0119 -> 119
func bcdToInt(data []byte, lenth int) int {
	buf := data[0:lenth]
	hexStr := fmt.Sprintf("%x", buf)
	out, _ := strconv.ParseInt(hexStr, 10, 32)
	return int(out)

}
func toZero(p []byte) {
	for i := range p {
		p[i] = 0
	}
}

/*
8583报文打包
*/
func (ea *Easy8583) Pack8583Fields() int {
	fmt.Printf("pack 8583 fieldsn")
	//ea.Txbuf[]
	ea.Txbuf = ea.Txbuf[0:23]
	toZero(ea.Txbuf)

	memcpy(ea.Txbuf[2:], ea.Tpdu, 5)
	memcpy(ea.Txbuf[7:], ea.Head, 6)
	memcpy(ea.Txbuf[13:], ea.Msgtype, 2)
	memcpy(ea.Txbuf[15:], ea.Bitmap, 8)

	j := 0
	len := 23
	tmplen := 0
	seat := 0x80
	for i := 0; i < 64; i++ {
		seat = (seat >> 1)
		if (i % 8) == 0 {
			j++
			seat = 0x80
		}
		if ea.Field_S[i].Ihave {
			ea.Bitmap[j-1] |= byte(seat)
			if ea.Field_S[i].Ltype == NOVAR {
				ea.Txbuf = ea.Txbuf[0 : len+ea.Field_S[i].Len]
				memcpy(ea.Txbuf[len:], ea.Field_S[i].Data, ea.Field_S[i].Len)
				len += ea.Field_S[i].Len

			} else if ea.Field_S[i].Ltype == LLVAR {
				ea.Txbuf = ea.Txbuf[0 : len+1]
				ea.Txbuf[len] = byte(ea.Field_S[i].Len)

				tmplen = bcdToInt(ea.Txbuf[len:],1)
				if ea.Field_S[i].Dtype == BCD {
					tmplen = ((tmplen/2) + (tmplen%2))
				}
				len += 1
				ea.Txbuf = ea.Txbuf[0 : len+tmplen]
				memcpy(ea.Txbuf[len:], ea.Field_S[i].Data, tmplen)
				len += tmplen

			} else if ea.Field_S[i].Ltype == LLLVAR {
				ea.Txbuf = ea.Txbuf[0 : len+2]
				ea.Txbuf[len] =   byte(ea.Field_S[i].Len>>8)
				ea.Txbuf[len+1] = byte(ea.Field_S[i].Len)

				tmplen = bcdToInt(ea.Txbuf[len:],2)
				if ea.Field_S[i].Dtype == BCD {
					tmplen = ((tmplen/2) + (tmplen%2))
				}
				len += 2
				ea.Txbuf = ea.Txbuf[0 : len+tmplen]
				memcpy(ea.Txbuf[len:], ea.Field_S[i].Data, tmplen)
				len += tmplen

			}

		}
		//报文总长度
		ea.Txbuf[0] = byte((len-2)>>8)
		ea.Txbuf[1] = byte((len-2))
		memcpy(ea.Len,ea.Txbuf,2)

	}

	return 0
}


/*
8583报文解包
*/
func (ea *Easy8583) Ans8583Fields( rxbuf []byte,rxlen int) int {
	fmt.Printf("ans 8583 fieldsn")
	ea.Init8583Fields(ea.Field_R)

	len := 0
	tmplen := 0
	bitMap := make([]byte,8)
	var seat,buf uint64 = 1,0

	memcpy(bitMap,rxbuf[15:],8)

	memcpy(ea.Len,rxbuf[0:],2)
	//memcpy(ea.Tpdu,rxbuf[2:],5)
	memcpy(ea.Head,rxbuf[7:],6)
	memcpy(ea.Msgtype,rxbuf[13:],2)
	memcpy(ea.Bitmap,rxbuf[15:],8)

	len += 23

	for i := 0;i < 8;i++ {
        buf = ((buf<<8) | uint64(bitMap[i]))
	}

	for i := 0; i < 64; i++ {
		if  (buf & (seat << uint(63 - i))) > 0 {
			ea.Field_R[i].Ihave = true
			if ea.Field_R[i].Ltype == NOVAR {
				ea.Field_R[i].Data = make([]byte,ea.Field_R[i].Len)
				memcpy(ea.Field_R[i].Data, rxbuf[len:], ea.Field_R[i].Len)
				len += ea.Field_R[i].Len

			} else if ea.Field_R[i].Ltype == LLVAR {
			
				ea.Field_R[i].Len = int(rxbuf[len])

				tmplen = bcdToInt(rxbuf[len:],1)
				if ea.Field_R[i].Dtype == BCD {
					tmplen = ((tmplen/2) + (tmplen%2))
				}
				len += 1
				ea.Field_R[i].Data = make([]byte,tmplen)
				memcpy(ea.Field_R[i].Data, rxbuf[len:], tmplen)
				len += tmplen

			} else if ea.Field_R[i].Ltype == LLLVAR {

				ea.Field_R[i].Len = ( ( int(rxbuf[len])<<8 ) | int(rxbuf[len+1] ) )

				tmplen = bcdToInt(rxbuf[len:],2)
				if ea.Field_R[i].Dtype == BCD {
					tmplen = ((tmplen/2) + (tmplen%2))
				}
				len += 2
				ea.Field_R[i].Data = make([]byte,tmplen)
				memcpy(ea.Field_R[i].Data, rxbuf[len:], tmplen)
				len += tmplen

			}

		}

	}

	if(len > rxlen){
        return 1;
	}
	
	return 0
}

/*
打印信息,调试用
*/
func (ea *Easy8583) PrintFields(fds []Field){
	fmt.Println("Print fields...")
	fmt.Printf("n==========================================n")
	fmt.Printf("Len:t%sn", bytesToHexString(ea.Len))
	fmt.Printf("Tpdu:t%sn", bytesToHexString(ea.Tpdu))
	fmt.Printf("Head:t%sn", bytesToHexString(ea.Head))
	fmt.Printf("Msge:t%sn", bytesToHexString(ea.Msgtype))
	fmt.Printf("Bitmap:t%sn", bytesToHexString(ea.Bitmap))
	fmt.Printf("n==========================================n")
	for i:=0; i < 64; i++{
		if fds[i].Ihave {
			fmt.Printf("[field:%d] ",i+1)
			if fds[i].Ltype == LLVAR{
				fmt.Printf("[len:%02x] ",fds[i].Len)
			}else if fds[i].Ltype == LLLVAR{
				fmt.Printf("[len:%04x] ",fds[i].Len)
			}
			
			fmt.Printf("[%s]n",bytesToHexString(fds[i].Data))
			fmt.Printf("n------------------------------n")
		
		}
	}
}

func main() {

	fmt.Println("test...")
}