Receipts from McDonald's in the UK include a code that allows you to complete an online survey as shown in the attached image (in the green box):
After gathering and comparing several receipts I have deduced that the codes use a base 25 alphanumeric system consisting of the following characters:
C M 7 W D 6 N 4 R H F 9 Z L 3 X K Q G V P B T J Y
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
25 would therefore be MC, 26 MM, 27 M7, etc.
The code for this receipt is 7MXW-NLH4-ZQ3K and can be broken down as follows:
| Code | Decimal | Meaning |
|---|---|---|
7MX |
1290 | Store ID. |
W |
3 | Not sure, but the vast majority of receipts always seem to have W here. |
NL |
163 | Order ID: last two digits + 125, so can be reversed by 163 % 125 which is 38. |
H4ZQ3K |
90,823,491 | Probably the date/time of purchase - more below. |
I have noticed that the last number (i.e. what I assume is the purchase date/time) increases with time when comparing receipts.
For example, another code's last 6 characters are H4F6XN (90,784,756) and the order was placed on 2022-12-27 19:10:05, just over a day before. A quick comparison:
| Order 1 | Order 2 | Difference |
|---|---|---|
| 90,823,491 | 90,784,756 | 38,735 |
| 2022-12-28 20:59:51 | 2022-12-27 19:10:05 | 92,986 (seconds) |
Dividing the difference of seconds by the difference of the 6 character number:
92,986 ÷ 38,735 = 2.4 (approx.)
It would therefore seem that the number increases by 1 every 2.4 seconds. The result of 60 ÷ 25 also happens to be 2.4 which means 1/25th of a minute can be represented by a character from the base 25 system.
Following the assumption of the number increasing by 1 every 2.4 seconds it seems that the first datetime (or "epoch") is approximately 2016-02-01 00:00:00.
Therefore to decipher the final value of H4ZQ3K in the first receipt:
- 90,823,491 × 2.4 = 217,976,378.4 seconds
- 2016-02-01 00:00:00 + 217,976,378.4 seconds = 2022-12-28 20:59:38.4
...but note how the predicted timestamp is incorrect - off by 12.6 seconds (the other receipt comes out at 2022-12-27 19:10:14.4 - 9.4 seconds ahead).
I'm stumped as to what's causing the error - does anyone have any ideas?
Some more codes for reference (note how the predicted timestamp is never more or less than 60 seconds):
| Code | Last 6 chars (decimal) | Purchased | Predicted | Ahead by (seconds) |
|---|---|---|---|---|
7MXW-NLH4-ZQ3K |
90,823,491 | 2022-12-28 20:59:51 | 2022-12-28 20:59:38.4 | -12.6 |
M3NW-YRH4-F6XN |
90,784,756 | 2022-12-27 19:10:05 | 2022-12-27 19:10:14.4 | +9.4 |
MNKW-M6H4-7FQX |
90,662,940 | 2022-12-24 09:57:46 | 2022-12-24 09:57:36 | -10 |
CRGW-ZYHN-KHBP |
90,490,545 | 2022-12-19 15:01:03 | 2022-12-19 15:01:48 | +45 |
CQMW-L9HN-KNC7 |
90,488,127 | 2022-12-19 13:25:56 | 2022-12-19 13:25:04.8 | -51.2 |
M9JW-QCH6-PT3Z |
90,170,362 | 2022-12-10 17:34:42 | 2022-12-10 17:34:28.8 | -13.2 |
7NLW-NFH6-7XLV |
89,884,719 | 2022-12-02 19:08:02 | 2022-12-02 19:08:45.6 | +43.6 |
MLZW-Y3HD-YTP9 |
89,842,386 | 2022-12-01 14:55:38 | 2022-12-01 14:55:26.4 | -11.6 |
MBQW-RCHD-YNQ9 |
89,832,311 | 2022-12-01 08:12:04 | 2022-12-01 08:12:26.4 | +22.4 |
MP4W-6DHM-QNNC |
88,550,775 | 2022-10-26 17:51:16 | 2022-10-26 17:51:00 | -16 |
7HGW-RFRG-9JX9 |
85,342,886 | 2022-07-29 15:15:30 | 2022-07-29 15:15:26.4 | -3.6 |
MJFW-YNRK-P66H |
84,690,759 | 2022-07-11 12:30:01 | 2022-07-11 12:30:21.6 | +20.6 |
CRFD-NZRZ-JZGP |
83,179,845 | 2022-05-30 13:13:26 | 2022-05-30 13:13:48 | +22 |
Python functions for encoding/decoding:
CHARS = "CM7WD6N4RHF9ZL3XKQGVPBTJY"
BASE = len(CHARS)
def encode(num):
encoded = ""
while num >= BASE:
encoded = CHARS[num % BASE] + encoded
num //= BASE
return CHARS[num] + encoded
def decode(encoded):
num = 0
for x, c in enumerate(encoded):
exp = len(encoded) - x - 1
num += (BASE*exp) CHARS.find(c)
return num
