EMV TLV 总结
转载自:https://blog.csdn.net/jzaicn/article/details/48546589
什么是TLV?
TLV结构是一种传输结构,一个buf,通过T(tag)索引,通过L(len)指定后续长度,通过V(value)保存指定长度
--------------------------------------------------------------------------------------
一个buf怎么解析成TLV?
现在有这么一个二进制字节流
6F328407A0000000031010A5278701019F38129F1A029F33039F40059F1B049F09029F35015F2D086573656E667264659F110101
如第一行所示,它就是一个由上面buf解析出来的TLV结构
tag 部分是 0x6F
len 部分是 0x32
value 部分是 二进制字节流 8407A0000000031010A527870101009F38129F1A029F33039F40059F1B049F09029F35015F2D086573656E667264659F110101
---------------------------------------------------------------------------------------
TLV一层层完全解析出来是什么样的?
对于TLV来讲,有两种格式,一种是基本格式(BER-TLV),一种是嵌套格式
对于本例的buf来讲,它就是一个复合的嵌套格式,完整解析出来应该是这个样子
整个buf是一个父节点,6F
他有两个子节点84 、A5
对于84节点,他是不可再分的基础格式
对于A5节点,他是一个父节点
可以再拆分为4个子节点87、 9F38、 5F2D、 9F11
----------------------------------------------------------------------------------------
为什么87 节点和 9F38节点中间有个白色的地方呢?
根据EMV文档规定,可能出于填充或者其他原因,tlv和tlv之间可能存在无意义的00字节,
在解析的时候应该无视它
----------------------------------------------------------------------------------------
那么为什么有的元素是基础元素,有的元素是嵌套结构呢?
类似于html,有些标签需要嵌套表示更特殊的意义。
tlv也同样如此,根据文档规定,在tag 的第一个字节里面的第六位表明了它是否是一个嵌套格式
我们来看几个例子。
本例中的6F (文件控制信息(FCI)模板)二进制表示为
0110 1111
它的第六位(下划线部分)就为1
本例中的A5 (文件控制信息(FCI)专有模板)二进制表示为
1010 0101
再来一个例子 BF0C (发卡行自定义数据)二进制表示为两个字节
1011 1111 0000 1100
---------------------------------------------------------------------------------------------------
为什么有的tag有两个字节,有的tag只有一个字节?
tag的编码规则是这样子的
编码规则
第一个字节 bit8~bit7 表明tag所属类型
00 通用级 universal class
01 应用级 application class
10 规范级 context-specific class
11 私有级 private class
第一个字节 bit6 表明本tag的value部分是否包含子tag
第一个字节 bit5~bit1 表明是否有第二个字节一起表示本tag
11111 全为1表示有第二个字节
第二个字节 bit8 为1,同时bit7~bit1 大于0 表示有下一个tag
第三~N个字节同第二个字节
举个栗子:
6F 84 A5 87
9F38 5F2D 9F11
可以看到两个字节的tag,第一个字节全是 奇数+F
在EMV中用到的tag只有两个字节
---------------------------------------------------------------------------------------------
那么len 会有两个字节吗?
当然,如果需要表示更长的内容,len就需要多字节,
因为需要控制是否有多个字节,所以第一个字节的最高一个位不能用于计数。
所以一个字节表示长度的情况,只有在value对应长度小于等于127时才会出现。
当大于127,就需要2个或更多字节记录长度。
编码规则
第一个字节 bit8 为1 表明本tag是用来记录后面用于表示Len的字节有多少个
第一个字节 bit8 为0 即保存数值为0-127表示为长度
第二个字节及后续的字节表示长度,以网络字节序表示
好了,举个栗子
本例中value部分是 0x32 二进制 是 0011 0010,
第8位为0,代表后7位表示长度,指示value长度为50字节
再举个栗子
现在有这么一个buf
704A8F01549F32030100019223BC39A45FC4937760FC611FABE5B7E1024F67D63D1E7208B952F110DB072738AE8EE7619F49159F02069F03069F1A0295055F2A029A039C019F37049F470103
解析后
7081FB9F4681F727E30864E9566480FC8DE906A9A3D28E9C5DB37556919FB4D0B8015B653F4F26F95538458ABF3A8162B20E2A46347158EB8FBF3781747015264FCE510C12FFA956486A472D964474F416B766667A7710637639D41B3FA3A5D93820E32DFD4A2FC01FB11D1C06866D8A0C5F8AEAAA401CACC59BE472B234DB09B8032CB73E8385D5C372001777B4BBCF170A05565448B72F63A4279BE692DD33817F5EF03C2689DDF3C38EB7BCCB70A17FBC64565429F4CD4DD93EC2B90D10C45E4603545D03475BB973F88FC489876E59DCDB08A40BA2D1983F3F74450EF85E51126B0B451E4C3AE22FCD33BF8D565421342FF69CE5D5914C121A8CDF2A
他的长度部分就为 81FB,意思是,第一字节表示后续用了1个字节表示长度
后续的那1个字节是FB,意味着value部分有251个字节。
好了那么现在要表示value部分长度为43981个字节
十六进制是ABCD
那么表示为TLV的L格式应该写成 0x82 AB CD
表示本次表示长度的后续字节有两个,分别是AB 和CD,凑成一起 0xABCD = 43981
EMV中 Len一般为2字节
----------------------------------------------------------------------------------------
那么value会有多个字节吗?
len都说多个字节了,那有多个字节是必须的,否则就是数据包出错了。
那么如果len表示字节数为0呢? 那么value应该不存在
---------------------