专栏首页独行猫a的沉淀积累总结嵌入式linux之go语言开发(四)go语言8583协议报文解析

嵌入式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:%s\n", 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 fields\n")
	//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 fields\n")
	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%s\n", bytesToHexString(ea.Len))
	fmt.Printf("Tpdu:\t%s\n", bytesToHexString(ea.Tpdu))
	fmt.Printf("Head:\t%s\n", bytesToHexString(ea.Head))
	fmt.Printf("Msge:\t%s\n", bytesToHexString(ea.Msgtype))
	fmt.Printf("Bitmap:\t%s\n", 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...")
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 人类能否驾驭浩瀚宇宙?

    宇宙,浩瀚的宇宙。有人知道它有无边界吗?如果有,那么边界之外又是什么呢?没人知道。

    特立独行的猫a
  • java版银联8583协议解析,超简单超直观的实现及示例(全互联网最简单)

    最近有需要把8383协议的解析用到android上,但是搜遍了整个互联网,没发现有哪个简单好用点的java版8583解析库。就自己动手自己做一个吧,让其尽可能的...

    特立独行的猫a
  • 移植lua5.2和luasocket库到嵌入式linux,使能强大的lua脚本和网络功能

    在嵌入式linux上,想最简单方便的使用网络资源,如ftp,http,和socket,用c实现容易吗?

    特立独行的猫a
  • Java Web 网络留言板6 MVC模式

    request.setAttribute("message", message);   request.getRequestDispatcher("/addR...

    Hongten
  • 如何在Ubuntu20.04 ubuntu/focal64 安装Python2

    python2 已经被官方抛弃了, 导致新的发型版ubuntu 20.04默认没有python2,

    扫地工程师
  • 聊聊dubbo的AccessLogFilter

    dubbo-2.7.3/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/Ac...

    codecraft
  • 聊聊dubbo的AccessLogFilter

    dubbo-2.7.3/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/Ac...

    codecraft
  • 数字电路实现中的DRC

    数字实现硅农大方向可分为前端后端或中端后端,再细分可分为综合、DFT、形式验证、PR, PV, PI, STA 等,细分之后各工种缝扣子的缝扣子,挂衣领的挂衣领...

    老秃胖驴
  • 在已经配置了Tensorflow的虚拟环境中配置Opencv

    在开发环境里面已经安装了tensorflw,但是有时候需要进行底层图像处理,需要配置opencv,下面介绍在虚拟环境中配置opencv的方法。

    于小勇
  • LeetCode88|两数之和IV-输入BST

    给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

    后端Coder

扫码关注云+社区

领取腾讯云代金券