

IMEIのチェックデジット、「右から偶数番目を2倍」だと逆になる
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
IMEI(15桁)の末尾1桁はチェックデジットで、Luhnアルゴリズムで算出される。クレジットカード番号の検証で使われているのと同じ方式。
計算自体は単純だけど、「どの桁を2倍するか」の説明で右からか左からか、奇数番目か偶数番目かがよく食い違う。同じ処理を指しているつもりで逆のことを書いてしまうケースがあるので、そこを整理する。
手順
対象は先頭14桁(チェックデジットを除いた本体部分)。
- 14桁を用意する
- 右から数えて奇数番目(1番目、3番目、5番目…)の桁を2倍する
- これはチェックデジットの直前の桁からスタートして1つおき、という意味
- 2倍した結果が10以上になったら各桁を足す(12 → 1+2=3)。これは「2倍して9を超えたら9を引く」と等価
- 全部の桁を合計してsumを作る
- チェックデジット
cd = (10 - (sum % 10)) % 10
ここでよくある書き間違いが「右から偶数番目を2倍」という表現。これだと2倍する桁がひとつずれて、算出される値も変わってしまう。「右から奇数番目」が正しい。
左から数える場合に言い換えると、0-indexedで奇数位置(インデックス1,3,5…)を2倍する、という書き方になる。右からの奇数番目と左からの奇数インデックスが一致するのは14桁が偶数長だから。
実装
digits = 14桁の配列(左から順)sum = 0for i in 0..13: d = digits[i] if i % 2 == 1: # 左から数えて2,4,6...番目 = 右から数えて奇数番目 d = d * 2 if d >= 10: d = d - 9 sum += dcheck = (10 - (sum % 10)) % 10検算
49015420323751(14桁)で計算してみる。
| 左からの位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 値 | 4 | 9 | 0 | 1 | 5 | 4 | 2 | 0 | 3 | 2 | 3 | 7 | 5 | 1 |
| 2倍対象 | - | ○ | - | ○ | - | ○ | - | ○ | - | ○ | - | ○ | - | ○ |
| 処理後 | 4 | 9 | 0 | 2 | 5 | 8 | 2 | 0 | 3 | 4 | 3 | 5 | 5 | 2 |
(2倍して10以上になった桁は9を引いている。9→9のままは18→1+8=9と同じなので変化なし)
合計 = 4+9+0+2+5+8+2+0+3+4+3+5+5+2 = 52
チェックデジット = (10 - 52%10) % 10 = (10-2)%10 = 8
→ 完成したIMEIは 490154203237518。これはLuhnアルゴリズムの説明でよく使われるサンプル値と一致する。
まとめると
- 2倍する桁は「右から奇数番目」であって「右から偶数番目」ではない
- 左から数えるなら0-indexedの奇数インデックス(2,4,6…番目)が対象で、これは右からの奇数番目と同じ集合を指している
- 説明文だけを見て実装すると、右/左・奇数/偶数の組み合わせを取り違えやすいので、実装した後は既知のサンプル値(490154203237518など)で検算しておくのが確実