EMV TLV 总结

来源:互联网 发布:华云数据 工资待遇 编辑:程序博客网 时间:2024/04/27 08:20

什么是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应该不存在



0 0