4. Access Codes
Access Codes are unique identifiers for AiMe cards. They can be divided into two categories:
- Old-style codes, starting with a
- Amusement IC codes, starting with a
I have seen reference to cards starting with
3, but never seen such a card.
4.1 Old-style codes
Old-style codes follow a simple and predictable formula. The first 5 digits identify the type of card, the following 8 digits are the card serial, encrypted, and the final 7 digits are a digest of the card serial.
Possible prefixes are listed in the following table:
|Prefix||Card type||Card key|
|0102 9||MJ4 Evo Mobile||
|0103 1||MJ4 Evo Card||
|0103 2||Diva Card||
|0103 3||Diva Mobile||
|0103 4||MJ4 Evo Pro Mahjong Player||
|0103 5||AiMe Mobile||
|0103 6||AiMe Card||
|0103 7||Crows Mobile||
|0103 8||Crows Card||
|0104 0||Sengoku Card||
The card serial is encrypted with a solitaire cipher, using the digest as the key.
Computing the digest is done as follows:
- Zero-prefix the serial number to 8 characters
- Compute the MD5 of the serial
- Shuffle the serial, using each nibble of the key as an index (ie
- Treating the 128-bit value as a single little endian number, XOR every 23 bits together (counting from LSB, such that the final operation will be performed on only 13 bits, which will include the MSB)
- Zero-prefix the result of the operation to 7 characters
The following python snippet implements this behavior with some nasty bit-string hacks. A less succinct but potentially nicer implementation would use bit shifts instead.
import hashlib def digest(serial: int, key: str): real_digest = hashlib.md5(str(serial).zfill(8).encode()).digest() digest = bytes(real_digest[int(key[i], 16)] for i in range(16)) bitstring = "".join(bin(i)[2:].zfill(8)[::-1] for i in digest)[::-1].zfill(6 * 23) computed = 0 while bitstring: work = int(bitstring[:23], 2) computed ^= work bitstring = bitstring[23:] return str(computed).zfill(7)
4.2 Amusement IC codes
Unfortunately these are largely a black-box. I’ll update this section if I ever figure anything else out, but I don’t expect to.