JAPAN RAIL PASS の QR コードの解析

執筆者:

カテゴリ:

JAPAN RAIL PASS (ジャパン・レール・パス) は訪日外国人旅行客向けに JR グループ各社が共同して販売している JR 全線及び JR 各社の路線バスに乗車できる特別企画乗車券です。この券面には、以下の画像の通りQR コードが印刷されています。

Emile Donzel – 投稿者自身による著作物, CC 表示-継承 4.0, https://commons.wikimedia.org/w/index.php?curid=147719677による

この内容は、以下の通りの 16 進数文字列です。

画像上: 010204FF04FC05FA07182CFD2FF02D040FF011EE13EC19500B6125FA07F809
画像下: 010204FF04FC05FA07182CFD2FF02D040FF011EE13EC19500B6117FA07F809

これは、以下のアルゴリズムでマスクされており、デコードする必要があります。

# マスクのカウンタが 1 に戻るまでの周期。
MASK_PERIOD: Final[int] = 20

# 先頭の非マスク領域の長さ。
HEADER_SIZE: Final[int] = 2


def mask_byte(index: int) -> int:
    """`index` 番目のバイトに加算されているマスク値を返す。"""
    if index < HEADER_SIZE:
        return 0
    counter = (index - HEADER_SIZE) % MASK_PERIOD + 1
    return counter if counter % 2 else -counter


def decode(payload: bytes) -> bytes:
    """QR コードから読んだ生バイト列を平文に戻す。"""
    return bytes((byte - mask_byte(index)) % 256 for index, byte in enumerate(payload))

デコードすると、以下のようになります。

画像上: 01020301010000000020230724FC2012000000000000185208652000000000
画像下: 01020301010000000020230724FC2012000000000000185208651200000000

領域 (バイト)内容
0–1ヘッダ (01 02)
9-12券面有効期限 (BCD 6 桁)
22-26 券面左下の第2・第3フィールド (BCD 10 桁、画像の券面では非表示)

まだ不明なフィールドがありますから、今後の研究に期待します。

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です