我在文档中发现,它们指的是SIMPLE-TLV和BER。我研究了大多数EMV和GP文档,但是他们没有提到不同的地方。
有人能帮我理解一下两者的区别吗?
发布于 2013-09-21 12:34:13
用于智能卡的ISO/IEC 7816-4数据字段
BER编码
这是ISO/IEC7816-4所使用的更常见的BER编码规范:
每个BER数据对象应由2个或3个连续字段组成(见ISO/IEC 8825和附件D)。 标记字段T由一个或多个连续字节组成。它编码一个类、一个类型和一个数字。长度字段由一个或多个连续字节组成。它编码一个整数L,如果L不是null,则值字段V由L个连续字节组成。如果L为null,则数据对象为空:没有值字段。
请注意,在当前标准中,ISO/IEC 7816只允许使用最多5个长度字节(指定的大小可达2^32-1字节)。也不支持不确定长度编码。这些限制是智能卡特有的。注意,在ISO/IEC 7816-4的后期版本中引入了4和5字节长度编码;早期的卡片/卡片读取应用程序可能只支持3个长度字节(即值大小可达64 4GiB字节,而不是4 4GiB)。
BER规范的扩展性要高得多(这就是为什么simple被称为"simple")。我不会说太多的细节,因为互联网上有很多可用的信息。仅举几个不同之处,标签具有句法意义,可能由多个字节组成,长度编码相当复杂。
通常,误码率只应用作ASN.1结构的编码,ASN.1语法定义该结构。然而,ISO 7816-4却搞砸了这一点,只直接指定了BER标记字节。
注意,有时指定DER而不是BER。在这种情况下,您应该只使用长度字段大小的最小字节数-例如,下面示例中的值为05
的单个长度字节。ISO/IEC规范的BER编码基本上是美国特定的X.690标准的副本,也反映在国际标准ISO/IEC 8825-1 (都是payware)中。
简单TLV编码
ISO/IEC 7816-4中的误码率规范遵循简单-TLV规范.SIMPLE-TLV是ISO 7816-4特有的.
每个简单的-TLV数据对象应该由两个或三个连续字段组成。 标记字段T包括仅编码从1到254的数字的单个字节(例如,记录标识符)。它没有编码类,也没有构造类型。长度字段由1或3个连续字节组成。如果length字段的前导字节在'00‘到'FE’之间,那么length字段包含一个编码整数L的单个字节,其值从0到254。如果前导字节等于'FF',那么length字段将在随后的两个字节上继续,后者编码一个整数L,其值从0到65535。如果L在中不为空,则值字段V由连续字节组成。如果L为null,则数据对象为空:没有值字段。
注意,标准忘记直接指定endianness。但是,您可以在ISO/IEC 7816-4中进行大端编码。
样本
以下示例都用于传递相同的标记号(定义字段)和值,但定义BER标记号31的示例除外。
样品简单-TLV
0F 05 48656C6C6F // tag number 15, length 5 then the value
0F FF0005 48656C6C6F // tag number 15, length 5 (two bytes), then the value
样本BER-TLV:
4F 05 48656C6C6F // *application specific*, primitive encoding of tag number 15, length 5 then the value
4F 8105 48656C6C6F // the same, using two bytes to encode the length
4F 820005 48656C6C6F // the same, using three bytes to encode the length
4F 83000005 48656C6C6F // the same, using four bytes to encode the length
4F 8400000005 48656C6C6F // the same , using five bytes to encode the length
5F0F 05 48656C6C6F // **invalid** encoding of the same, with two bytes for the tag, specifiying a tag number 15 which is smaller than 31
5F1F 05 48656C6C6F // application specific, primitive encoding of **tag number 31**
在使用两个字节标记编码的最后一个示例中,第一个字节是40个十六进制,其中前3个最左边的位010指定应用程序特定的编码,将魔术值1F ( 31 )添加到其中,以指示另一个字节将跟随实际的标记号,同样是1F,因此值31。
差异
应当指出以下不同之处:
发布于 2013-09-19 08:02:54
简单的TLV只是由标记(或类型)、长度和值组成。
BER是一种特殊的TLV,它的值中包含一个或多个TLV .因此,它具有复合结构。
Tag1 Len1 Tag2-Len2-Value2 Tag3-Len3-Value3 ... TagN-LenN-ValueN
------------------------Value1------------------------
发布于 2022-11-05 22:00:17
Bert-Tlv解析器的示例C#代码: 1https://github.com/umitkoc/BertTlv
public class Tlv : ITlv, IFile
{
List<TlvModel> modelList=new();
string parser = "";
string length = "";
String empty = "";
string ascii = "";
int decValue = 0;
int step = 0;
public Tlv(String data)
{
TlvParser(data.Replace(" ",""));
}
public void readTag()
{
String line = "";
StreamReader sr = new StreamReader("taglist.txt");
while ((line = sr.ReadLine()) != null)
{
modelList.Add(new()
{
tag = line.Split(",")[0].Trim(),
description = line.Split(",")[1].Trim()
});
}
sr.Close();
}
public void insertTag()
{
try
{
StreamWriter sw = new StreamWriter("test.txt");
foreach (var item in modelList)
{
sw.WriteLine($"{item.tag},{item.description}");
}
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
public int writeFile(String parser)
{
StreamWriter sw = new StreamWriter("output.txt");
sw.WriteLine(parser);
sw.Close();
return 0;
}
private int TlvParser(String data, int i = 0, string tag = "")
{
if (i == 0)
{
readTag();
}
if (i < data.Length)
{
tag += data[i];
TlvModel model = getTag(tag);
if (model != null)
{
decValue = int.Parse(data.Substring(i + 1, 2), System.Globalization.NumberStyles.HexNumber);
// lengthControl(data,i+3,decValue);
if (model.description.Contains("Template"))
{
parser += $"{empty}|------ tag: {model.tag}({model.description})\n";
step += 1;
empty = Empty();
return TlvParser(data, i + 3, "");
}
else
{
parser += $"{empty}|------ tag: {model.tag}({model.description}){empty}|------ value --> {ConvertHex(data.Substring(i + 3, decValue * 2))} \n";
}
i += 3 + decValue * 2;
return TlvParser(data, i, "");
}
else
{
return TlvParser(data, i + 1, tag);
}
}
return writeFile(parser);
}
public TlvModel getTag(string tag)
{
return modelList.Find(i => i.tag == tag);
}
public string ConvertHex(string hex)
{
ascii = "";
for (int i = 0; i < hex.Length; i += 2)
{
ascii += System.Convert.ToChar(System.Convert.ToUInt32(hex.Substring(i, 2), 16));
}
return ascii;
}
private string Empty()
{
for (int s = 0; s < step; s++)
{
empty += "\t";
}
return empty;
}
public void setTag(TlvModel model)
{
modelList.Add(model);
insertTag();
}
}
https://stackoverflow.com/questions/18853800
复制相似问题