EMV TLV Java-функция

Я ищу способ перевести EMV-ответ с Java, например, с помощью этой онлайн-опции:

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

где вы положили что-то вроде этого ответа EMV:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

и он покажет вам все отлично, я начал что-то делать сам, но потом я понимаю, что, возможно, у нас может быть две строки 9F38(PDOL), а не два одинаковых тега, потому что я знаю, что это невозможно, но, возможно, значение тега заканчивается в 9F и начало следующего тега было бы 38, и это дало бы мне ошибку... Теперь, когда я упомянул это, возможно ли это? Потому что это было одной из главных причин, почему я перестал делать свою собственную функцию..

Кто-нибудь из вас уже написал функцию для этого?

Спасибо!

3 ответа

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

В этом проекте есть код для работы с данными EMV http://code.google.com/p/javaemvreader/

Ты на правильном пути. Вы можете легко создать свой собственный анализатор EMV, используя технику вызова TLV (Tag Length Value). Ваши необработанные данные всегда возвращаются с тегом, и после того, как тег является длиной, использование длины может дать вам значение.

Итак, создайте три метода

Метод 1: Содержит все короткие теги Метод 2: Содержит все длинные теги Метод 3: Содержит все собственные теги

Поэтому, когда вы передаете свой необработанный тег emv:

6f3a8407a0000000031010a52f500b56495341204352454449548701015f2d086573656e707466729f12074352454449544f9f1101019f38039f1a02

Переберите все эти три метода, и вы получите всю необходимую информацию.

Используйте функцию ниже, которая даст вам хэш-карту значения 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;
}
Другие вопросы по тегам