6

我正在寻找一种使用 Java 翻译 EMV 响应的方法,例如使用此在线选项:

http://www.emvlab.org/tlvutils/

您在其中放置类似 EMV 响应的内容:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

它会完美地向您展示一切,我开始自己做一些事情,但后来我意识到也许我们可以有两个 9F38(PDOL) 字符串,而不需要两个相同的标签,因为我知道这是不可能的,但标签的值可能以 9F 结尾并且下一个标签的开头将是 38,这会给我一个错误......现在我提到它,这可能吗?因为这是我停止做自己的功能的主要原因之一。

你们中是否有人已经编写了一个函数来做到这一点?

谢谢!

4

4 回答 4

9

https://github.com/binaryfoo/emv-bertlv应该可以解决问题。

使用您的示例,以下代码:

List<DecodedData> decoded = new RootDecoder().decode("6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02", "EMV", "constructed");
new DecodedWriter(System.out).write(decoded, "");

将输出:

[6F (FCI template)] 8407A0000000031010A52F500B56495341204352454449548701015F...1A02
[84 (dedicated file name)] A0000000031010
[A5 (FCI proprietary template)] 500B56495341204352454449548701015F2D086573656E707466729F...1A02
  [50 (application label)] VISA CREDIT
  [87 (application priority indicator)] 01
  [5F2D (language preference)] esenptfr
  [9F12 (application preferred name)] CREDITO
  [9F11 (issuer code table index)] 01
  [9F38 (PDOL - Processing data object list)] 9F1A02
    9F1A (terminal country code) 2 bytes
于 2014-11-07T12:44:57.623 回答
3

这个项目有代码来处理 EMV 数据http://code.google.com/p/javaemvreader/

于 2013-12-18T11:04:02.337 回答
1

你在正确的轨道上。您可以使用称为 TLV(标签长度值)的技术轻松构建自己的 EMV 解析器。您的原始数据总是带有标签,然后在标签是长度之后,使用长度可以获得值。

所以创建三个方法

方法1:包含所有短标签方法2:包含所有长标签方法3:包含所有专有标签

因此,当您传入原始 emv 标签时:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

遍历所有这三种方法,它将为您提供所需的所有有用信息。

于 2017-03-01T07:08:46.587 回答
0

使用下面的函数,它将为您提供 TLV 值的哈希图

public LinkedHashMap parseBERTLVTag(String tlv) throws DecoderException
{
    if(tlv==null || "".equalsIgnoreCase(tlv)){
        return null;
    }

    System.out.println("============= START ["+tlv+"]==================");


    boolean inTagRead= true;
    Map<String,String> tags= new HashMap<>();

    StringBuilder _tmp = new StringBuilder();
    String lastTag = "";
    int old_index = 0;
    boolean isFirstTagByte = true;
    int len = 0;
    boolean more=true;
    String data = "";
    while (more)
    {
        len = 0;
        String hByte = tlv.substring(old_index,(old_index = old_index+2));
        if(inTagRead)
        {
            if(isLastTagByte(hByte, isFirstTagByte))
            {
                inTagRead=false;
                _tmp.append(hByte);
                lastTag =  _tmp.toString();
                System.out.println("Tag["+lastTag+"]");
                tags.put(lastTag, null);
                _tmp= new StringBuilder();
            }else
            {
                _tmp.append(hByte);
            }

            isFirstTagByte = false;

        }else//Length
        {

            isFirstTagByte = true;


            if(isLastLengthByte(hByte)) {
                inTagRead=true;
                _tmp.append(hByte);
                len =  Integer.parseInt(_tmp.toString(), 16 );
                //read len*2
                System.out.println(" Length ["+len+"]");
                data =  tlv.substring(old_index, (old_index = old_index+len*2));
                String tmpData= lastTag+":"+_tmp.toString()+":h"+data;
                System.out.println(" Data ["+tmpData+"]");
                _tmp = new StringBuilder();

                tags.put(lastTag, tmpData);

            }else
            {
                _tmp.append(hByte);
            }

        }

        more= tlv.length()<=old_index?false:true;

        System.out.println("tag "+lastTag+" value "+data+"  length "+len);

        if(lastTag.length() > 0 && data.length() > 0 && len > 0){

            if(!map.containsKey(lastTag)){

                map.put(lastTag,new TLVModel().setTag(lastTag).setLength(len).setValue(data));
            }
        }

    }//END OF WHILE


    System.out.println("------------  as MAP  ---------------------");
    System.out.println("size "+map.size());

    for (Map.Entry mp:map.entrySet()){
        System.out.println("key  "+mp.getKey()+"  value "+mp.getValue());
    }

    return map.size() > 0 ? map : null;
}
于 2019-09-25T07:04:51.010 回答