KDE PIM/KItinerary/SBB Barcode: Difference between revisions
< KDE PIM | KItinerary
No edit summary |
|||
Line 5: | Line 5: | ||
* Strings seem to be UTF-8 encoded. | * Strings seem to be UTF-8 encoded. | ||
* Seems to be a sequence of variable length records, rather than a fixed binary layout, could be some form of TLV encoding (there are some similarities to ASN.1 BER/DER for example). | * Seems to be a sequence of variable length records, rather than a fixed binary layout, could be some form of TLV encoding (there are some similarities to ASN.1 BER/DER for example). | ||
* Records consist of a 1 byte type field, a | * Records consist of a 1 byte type field, a length field and N content bytes. | ||
* The type field | * For strings, the length is the amount of bytes needed to represent the UTF-8 string, not the amount of characters. | ||
* The type field does not seem to describe semantics, as values repeat for different values (rather than a data type of some form?). This would suggest that the record order defines their semantics. The presence of null records suggests that too, as well as the same record sequence in all samples. | |||
* It is possible that there is a multi-byte length encoding comparable to BER/DER. | * It is possible that there is a multi-byte length encoding comparable to BER/DER. | ||
* The first 10 bytes don't seem to match the pattern yet, but that might be due to unknown multi-byte length encoding (could be a record containing the entire ticket). | * The first 10 bytes don't seem to match the pattern yet, but that might be due to unknown multi-byte length encoding (could be a record containing the entire ticket). | ||
= Record Structure = | |||
* 1 byte type, although no idea what that indicates. Largely doesn't match the BER/DER type byte. | |||
* Length: | |||
** for values <= 127 byte this is just one byte | |||
** for value larger than 127 this is encoded in two bytes. This is quite different from BER/DER multi-byte length encoding however. It looks like a little endian layout , with the most significant bit of the first length byte being removed and the second byte being shifted by one bit to fill that space. | |||
* N bytes of content, with varying data types. | |||
= Record Sequence = | = Record Sequence = |
Revision as of 17:27, 27 February 2020
General Observations
- QR code, content has variable length at around 330 bytes.
- Contains readable strings as well as binary parts.
- Strings seem to be UTF-8 encoded.
- Seems to be a sequence of variable length records, rather than a fixed binary layout, could be some form of TLV encoding (there are some similarities to ASN.1 BER/DER for example).
- Records consist of a 1 byte type field, a length field and N content bytes.
- For strings, the length is the amount of bytes needed to represent the UTF-8 string, not the amount of characters.
- The type field does not seem to describe semantics, as values repeat for different values (rather than a data type of some form?). This would suggest that the record order defines their semantics. The presence of null records suggests that too, as well as the same record sequence in all samples.
- It is possible that there is a multi-byte length encoding comparable to BER/DER.
- The first 10 bytes don't seem to match the pattern yet, but that might be due to unknown multi-byte length encoding (could be a record containing the entire ticket).
Record Structure
- 1 byte type, although no idea what that indicates. Largely doesn't match the BER/DER type byte.
- Length:
- for values <= 127 byte this is just one byte
- for value larger than 127 this is encoded in two bytes. This is quite different from BER/DER multi-byte length encoding however. It looks like a little endian layout , with the most significant bit of the first length byte being removed and the second byte being shifted by one bit to fill that space.
- N bytes of content, with varying data types.
Record Sequence
starting at offset 10:
Nesting Depth | Type Id | Content Type | Meaning | Notes |
---|---|---|---|---|
1 | 0x12 | nested record | ||
2 | 0x0A | 2bytes followed by nested records | ? | 0x08 04 |
3 | 0x12 | string | ticket type? | "Point-to-point Ticket", "Supersaver Ticket" |
2 | 0x12 | string | Departure station | |
2 | 0x1A | string | Arrival station | |
2 | 0x20 | 2 byte | ? | 0x2801 in all samples |
2 | 0x32 | string | Via | |
2 | 0x38 | 1 byte | ? | 0x42 in all samples |
2 | 0x42 | 7 byte | ? | date/time? |
2 | 0x4A | 7 byte | ? | date/time? |
2 | 0x60 | variable, null terminated | ? | 2-3 bytes in all samples |
2 | 0x7A | string | ticket type or tariff | parenthesis enclosed abbreviations, string is also printed on the ticket |
2 | 0x88 | 1 byte | ? | null |
2 | 0x98 | 1 byte | ? | 0x02 |
2 | 0xA0 | 1 byte | ? | null |
1 | 0x1A | nested record | ? | |
2 | 0x0A | string | ? | 8 digit number |
2 | 0x12 | string | ? | 36 char uuid |
2 | 0x1A | string | family name | |
2 | 0x22 | string | given name | |
2 | 0x2A | 7 byte | ? | date/time? - possibly traveler birth date |
2 | 0x3A | string | tariff information? | "HALBTAX" |
1 | 0x2A | nested record | ? | |
2 | 0x0A | 7 byte | ? | date/time? |
2 | 0x10 | 4 byte | ? | followed by 0x200B outside of TLV structures? |
1 | 0x32 | nested record | price information? | |
2 | 0x0A | string | ? | "PCD" |
2 | 0x12 | string | currency | "CHF" |
2 | 0x1A | string | ticket price | |
1 | 0x3A | null | ? | |
1 | 0x42 | nested record | train information | not present in unbound tickets |
2 | 0x5A | string | train number | |
2 | 0x70 | null | ||
2 | 0x78 | null | ||
1 | 0x48 | 7byte, no length byte!?! | ? | breaks the overall TLV structure?? almost fixed value in all samples |
1 | 0x0A | string | ? | 4 digit number (3342 in all samples) |
1 | 0x12 | string | ? | 5 digit number (00001 in all samples) |
1 | 0x2A | nested record | ||
2 | 0x30 | nested record | see KDE_PIM/KItinerary/Thalys_Barcode, same structure there | |
3 | 0x02 | 20-21 byte | ? | signature? |
3 | 0x02 | 20-21 byte | ? |