-
Notifications
You must be signed in to change notification settings - Fork 72
Troika
Troika (Тройка) is the ticketing system used in Moscow, Russia. It uses MIFARE Classic 1K or 4K cards, and some cards also act as Podorozhnik or Strelka.
Support for this card is added in Metrodroid 2.9.35
These cards store data in sectors 7 and 8, which has a fixed key common to every card. You will need to acquire this key and install it into Metrodroid.
All numbers on the card are stored as big-endian. Record lengths are shown in bits, inclusive of the first and last bits, unless otherwise specified.
Sector | Block | Content |
---|---|---|
0 | 0 | UID/manufacturing info |
0 | 1-2 | zero-filled |
1 | 0-2 | zero-filled |
2 | 0 | unknown |
2 | 1-2 | 0xff-filled |
3 | 0-2 | 0xff-filled |
4 | 0-2 | Ticket block (alternative magic) |
5 | 0-2 | Zero-filled |
6 | 0-2 | 0xff-filled |
7 | 0-2 | Ticket block (multi-ride pass) |
8 | 0-2 | Ticket block (balance, e-purse) |
9-14 | 0-2 | Zero-filled |
15 | 0-2 | 0xff-filled |
For card combined with Podorozhnik there are following changes:
- 40 sectors instead of 16 (MiFare 4K instead of 1K)
- Sectors 1-3,6-9,13-15 stay unchanged
- Sectors 4-5, 10-12 are used for Podorozhnik, same way as normal Podorozhnik
- Podorozhnik sectors 8 and 9 are relocated to sectors 30 and 31 respectively
- Keys for sectors 16-29, 32-33 and 36-39 are unknown
- Sectors 34-35 are additional sectors for Troika and look zero-filled
Ultralight variant (paper ticket) has following layout:
Page | Content |
---|---|
0-3 | UID/manufacturing info |
4-15 | Ticket block |
Every ticket block starts with the same preamble:
First | Last | Length | Field description |
---|---|---|---|
0 | 11 | 12 | Magic. 0x45d (main) or 0x421 (alternate) |
12 | 19 | 8 | Ticket type |
20 | 51 | 32 | Serial number |
52 | 55 | 4 | Layout number |
Known ticket types are for main magic:
Magic | Ticket |
---|---|
0x3d | Empty |
0x9b | Single-ride |
0x9c | Two-ride |
0xa0 | 20 rides |
0xb1 | purse (balance) |
0xd3 | 60 rides |
For alternative magic so far only ticket 0x35 (empty) is known
This was seen only on empty slots. So it's not very well understood
First | Last | Length | Field description |
---|---|---|---|
0 | 55 | 56 | Preamble |
56 | 71 | 16 | Expiry date, in days since 1992-01-01 |
72 | end | Always zero |
First | Last | Length | Field description |
---|---|---|---|
0 | 55 | 56 | Preamble |
56 | 66 | 11 | Always zero |
67 | 75 | 9 | Validity start, in days since 2016-01-01 |
76 | 94 | 19 | Validity length, in minutes |
95 | 95 | 1 | Always zero |
96 | 114 | 19 | Last validation, in minutes since validity start |
115 | 118 | 4 | Always zero |
119 | 125 | 7 | Last transfer, in minutes after last validation |
126 | 127 | 2 | Encoded last transports, part 1 |
128 | 135 | 8 | Remaining trips |
136 | 151 | 16 | Last validator |
152 | 159 | 8 | Encoded last transports, part 1 |
160 | 191 | 32 | Always zero |
192 | 223 | 32 | Hash |
224 | 383 | 128 | Copy of 64-223 |
First | Last | Length | Field description |
---|---|---|---|
0 | 55 | 56 | Preamble |
56 | 63 | 8 | Always zero |
64 | 79 | 16 | Use before, in days since 1992-01-01 |
80 | 95 | 16 | Always zero |
96 | 127 | 32 | Copy of 80-95 |
128 | 143 | 16 | Validity start, in minutes since 1992-01-01 |
144 | 151 | 8 | Validity length, in days |
152 | 154 | 3 | Always zero |
155 | 159 | 5 | Last transfer, in 5-minutes after last validation |
160 | 161 | 2 | Encoded last transports, part 1 |
162 | 165 | 4 | Always zero |
166 | 175 | 10 | Remaining trips |
176 | 191 | 16 | Last validator |
192 | 223 | 32 | Hash |
224 | 239 | 16 | Last validation date, in days since 1992-01-01 |
240 | 250 | 11 | Last validation time, in minutes after midnight |
251 | 252 | 2 | Encoded last transports, part 2 |
253 | 255 | 3 | Always zero |
256 | 383 | 128 | Copy of 128-255 |
This is actually a meta-layout which just specifies sublayout
First | Last | Length | Field description |
---|---|---|---|
0 | 55 | 56 | Preamble |
56 | 60 | 5 | Sublayout number |
First | Last | Length | Field description |
---|---|---|---|
0 | 55 | 56 | Preamble |
56 | 60 | 5 | Sublayout number = 1 |
61 | 69 | 10 | Always zero |
71 | 86 | 16 | Use before, in days since 1992-01-01 |
87 | 96 | 10 | Always 0x13d |
97 | 112 | 16 | Validity start, in days since 1992-01-01 |
113 | 130 | 18 | Always zero |
131 | 150 | 20 | Validity length, in minutes |
151 | 153 | 3 | Always zero |
154 | 161 | 8 | Last transfer, in minutes after last validation time |
162 | 162 | 1 | Always zero |
163 | 164 | 2 | Last transport (1=subway, 2=monorail, 3= ground transportation) |
165 | 166 | 2 | Unknown |
167 | 176 | 10 | Remaining trips |
177 | 192 | 16 | Last validator |
193 | 195 | 3 | Always zero |
196 | 215 | 20 | Last validation, in minutes before the validity end |
216 | 223 | 8 | Always zero |
224 | 255 | 32 | Hash |
256 | 383 | 128 | Copy of 128-255 |
First | Last | Length | Field description |
---|---|---|---|
0 | 55 | 56 | Preamble |
56 | 60 | 5 | Sublayout number = 3 |
61 | 76 | 16 | Expiry date of purse, in days since 1992-01-01 |
77 | 87 | 11 | unknown, looks like always 0x2a4. May be ticket type (normal or concession) |
88 | 127 | 40 | Always zero. May be RFU |
128 | 143 | 16 | Last validator |
144 | 166 | 23 | Last validation time, in minutes after 2016-01-01 |
167 | 170 | 4 | Always zero. |
171 | 177 | 7 | Last transfer, in minutes after last validation time |
178 | 187 | 10 | Encoded last transports |
188 | 209 | 22 | Balance, in kopeyka (0.01 RUB) |
210 | 211 | 2 | Fare code (1=Edinyj, 2 = 90 minutes |
212 | 223 | 12 | Always zero. |
224 | 255 | 32 | Hash |
256 | 383 | 128 | Copy of 128-255 |