メニュー

チェックディジットのアルゴリズム:mod-10・mod-11・mod-97

チェックディジットのアルゴリズムを一族としてとらえ、mod-10、mod-11、mod-97 の違いと、方式を選ぶときに確認すべき四つの論点を整理します。

公開日

  • チェックディジット
  • アルゴリズム

チェックディジットのアルゴリズムは、一つひとつが独立した発明ではなく、同じ骨格を共有する一族です。前半の位に重みを掛けて足し、決められた数で割り、余りかその補数を末尾の一位に写す。この骨格を保ったまま、重み、法、余りの写し方だけを差し替えたものが各方式になります。この記事では、方式の違いが実務で何を意味するのかを軸に整理します。

チェックディジットのアルゴリズムにはどのような一族があるのか?

公開されている方式は、行っている計算の種類で大きく三つの系統に分けられます。

系統 割る数 主な用途の性格
mod-10 系 10 数字だけの短い番号
mod-11 系 11 数字と英字を含む番号
mod-97 系 97 長い番号

mod-10 系の中には、一位おきに値を二倍してから足す変種があります。カード番号で使われる算法もこの変種の一つで、詳しい規則と手計算の手順はカード番号の検証の側で扱っています。ここでは族の一員として名前を挙げるだけにとどめます。

mod-11 系は国際規格としてまとめられた一群を含み、余りをそのまま使う変種と、余りを別の値に読み替える変種があります。mod-97 系は割る数が大きいため、長い文字列でも偏りが小さくなり、国際的な長番号の検証に向いています。

重みと法はどのように変えられるのか

族の内部で調整できるのは、主に三つの点です。

  • 重みの並び。すべての位に同じ重みを掛ける方式もあれば、位ごとに違う重みを掛ける方式もあります。重みを周期的に巡回させる方式が実務では多く使われます。
  • 法の大きさ。割る数を大きくするほど、区別できる余りの種類が増えます。
  • 余りの写し方。余りをそのまま使う、補数を取る、特定の余りだけを特別な文字に置き換える、といった選択があります。

法が十を超えると余りが二桁になり得ます。これをそのまま末尾に置けないため、方式ごとに読み替えの規則が決められています。英字を一文字だけ許して残りを数字で埋める、といった扱いがその代表です。方式を選ぶとき、この読み替えが扱いやすいかどうかは見落とされがちですが、後から必ず効いてきます。

隣り合う二桁の入れ替えを捕まえられる方式はどれか?

同じ種類の誤りでも、方式によって捕まえやすさが変わります。ここが選定で最も実務的な差になります。

  • 一文字の書き間違いは、重みがどうであれ、ほぼどの方式でも見つかります。ある位の値が変われば合計も変わるからです。
  • 隣り合う二桁の入れ替えは、重みが対称だと見つかりません。二つの位の重みが同じであれば、入れ替える前後で合計が変わらないためです。
  • 重みが位ごとに違えば、入れ替えでも合計が変わり、誤りとして検出できます。

人の手入力が多い場面では、桁の入れ替えは珍しくありません。数字の並びを写し間違えるのではなく、指の順序が入れ替わる種類の誤りです。したがって、重みが非対称な方式を選ぶことには、はっきりした理由があります。

方式を選ぶときに本当に問うべき四つのこと

新しい番号の体系を設計する、あるいは既存の体系を検証対象に加えるとき、確認すべき論点は次の四点に集約されます。

  1. 番号はどのくらいの長さになるか。長さが想定できると、法の選定と実装の分割単位が決まります。
  2. 文字種は数字だけか、英字を含むか。英字を含むなら、余りの読み替え規則が必要になります。
  3. 誤りは主に人の入力から来るのか、機械の生成から来るのか。人の入力が主なら、入れ替えに強い設計が要ります。
  4. チェックディジットが二桁になる場合にどう表すか。ここを決めずに実装を始めると、後で表現が破綻します。

四つとも先に決めておけば、実装の途中で方式を変える事態を避けられます。

独自の規則を発明してはいけない理由

複数の制度をまたいで検証するとき、規則を自前で作るのは避けてください。制度が公開している説明に従って実装し、その制度が公開している例で自己点検するのが原則です。

自前の規則は、その場では動いているように見えます。しかし制度側が番号の桁や構成を変えた瞬間に、静かに誤った判定を返し始めます。外部から見て正しさを説明できない検証は、たとえ偶然合っていても、検証としての役に立ちません。

開発者向け:族としてまとめて実装する

族としてみると、実装は共通部分と差分に分けられます。共通部分は、正規化、重みの適用、総和、法による除算、余りからチェックディジットへの写像です。差分は、重みの並び、法、そして写像の規則だけです。

この分け方にすると、方式ごとに関数を複製する必要がなくなります。表として持てる部分は表にし、写像だけを方式ごとの小さな関数にします。新しい方式が増えたときも、足すのは一つの表と一つの写像になり、既存の方式の挙動は変わりません。詳しい検証の流れは番号検証の仕組みにまとめています。

なお、本記事で触れたパラメータは公開されている一般知識であり、例として挙げた数字は算法の説明のために構成した作り物です。どれも実際の制度が発行した番号ではなく、特定の主体を指すものではありません。

次の一手

自分の扱っている番号が、どの族のどの変種に当たるかを一度書き出してみてください。族が分かると、桁を増やすときに何が起きるかの見当がつきます。国際的な長番号の例はIBAN の構造と mod-97 検証で扱っています。手元の値で試すなら番号検証ツールに貼り付けるのが手軽です。検証位を持つ番号と持たない番号の違いはチェックディジットがない番号で整理しています。

続けて読む

カード番号・公的番号の検証ツールの関連記事