【问题标题】:EMV TLV Java FunctionEMV TLV Java 函数
【发布时间】:2013-05-04 00:40:08
【问题描述】:

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

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

您在哪里放置了类似 EMV 响应的内容:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

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

你们中的任何人是否已经编写了一个函数来执行此操作?

谢谢!

【问题讨论】:

    标签: java function emv tlv


    【解决方案1】:

    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
    

    【讨论】:

    • 我怎样才能从这个列表中获得特定的价值
    【解决方案2】:

    本项目有处理EMV数据的代码http://code.google.com/p/javaemvreader/

    【讨论】:

      【解决方案3】:

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

      所以创建三个方法

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

      所以当你传入你的原始 emv 标签时:

      6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

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

      【讨论】:

        【解决方案4】:

        使用下面的函数,它会给你 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2016-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多