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;
}