Decode that!
Check out my feeble attempt of writing my first Javascript*. The script looks into the data of QR codes and shows the content in human-readable format. It understands a bit of generic ASN.1, EMV and some other standards that are built on top of the EMV standards, for instance, QCAT, GCASH Transit and QRPH.
If you have any fare collection or payment QR code, you can find out what data it contains. Please consider sending it to me for further improvement of this little javascript app.
(* I cheated a bit and used Kotlin/Multiplatform, but still …)
You can find the source code on Github.
The idea is to first convert the data into an intermediate TLV structure, which is independent of the original encoding. Secondly, the TLV structure (which is a tree) will be "stringified". This means the script tries to find the names of the tags and the meaning of the value of the TLV objects in order to convert the value portion of the TLV into a human-readable string.
String to Bytes Conversion
This JavaScript interprets the input string as ASCII, hexadecimal or Base64 string, and then converts the string to an array of bytes. ASCII means that every character represents one byte, encoded according to UTF-8 rules. For instance, "01" represents an array of two bytes: [0x30, 0x31]. In "hexadecimal" notation, the same byte array will be represented by this string: "3031" and in "BASE64" notation is would look like this: "AQI=".
Conversion into a TLV Structure
Then the script attempts to parse the byte array using the ASN.1/BER or "EMV Merchant-presented" encoding rules. For example, an ADF Name "GCASH" (tag: 0x4F, length: 5) would be encoded in BER as follows: [0x4F, 0x05, 0x47, 0x43, 0x41, 0x53, 0x48] in the ASCII (i.e. EMV Merchant -presented) encoding it would (in theory) look like this: [0x34, 0x46, 0x30, 0x35, 0x47, 0x43, 0x41, 0x53, 0x48].
Analysis of the TLV Structure
The resulting TLV structure will then be interpreted according to the EMV Customer presented standard or the EMV merchant presented standard. The script also understands some standards that are built on top of the EMV standards, for instance, QCAT, GCASH Transit and QRPH.
Display of the Results
If "INCLUDE HEX DUMP" is checked, the value of each tag (apart from templates) will be shown in hex notation.
If "RAW TLV ONLY" is checked, the script will not attempt to find tag names and formatting for values.
For standards that I do not have access to, I am only guessing the names of tags and the string representation of the TLV values.