英語・ダイエット・その他徒然なるままに

趣味の英語学習(TOEIC 970点)やダイエットの成功談など、色々書いていきます。

マイナンバー (3)

2015年10月31日 15時34分52秒 | コンピュータ
前回は準備で終わってしまいましたが、マイナンバーのC/Dの生成方式である「モジュラス11ウェイト2-7」の亜種2つを取り上げ、誤り検出率の観点から議論してみよう、というのが今回の目的でした。数学が凄く得意、あるいは、符号理論に造詣のある人からすると(私はないです)、私が何を言わんとしているかは既に自明かもしれませんが、まあ、まったりとお付き合い下さい。数学なんか大嫌いという人は、まあ頭の体操だと思って読んでみて下さい。実体は小学校の算数レベルの話ですから。

で、議論再開の前に1つだけ訂正なのですが、「ウェイト2-7」と表記する場合と「ウェイト2~7」と表記する場合とでは積和の作り方が違う、というような事を書いてあるサイトもあります(本当の所どうなのかは知りません)。それによると、マイナンバーのように下の桁から順番に1つずつずらした桁の重みを表す場合は「ウェイト2~7」と書くのだそうで、ウェイト2-7と書くと積和の計算式が違うのだそうです。確かに積和の作り方にも亜種があるというのはなんとなく知ってはいたのですが、こういう表記の仕方で区別するというのは知りませんでした。重ね重ね、本当の所は知りませんが、そういう説明をしているサイトもあるので、念のため今後は「モジュラス11ウェイト2~7」と書くことにします。

さて、符号の誤り検出率という言葉を前回出しました。C/Dの役割は、どこかで数字を間違えた場合にそれを”検出”することでしたね。じゃあ、数字をどんな風に間違えても必ずきちんと検出できるのか、とか、どんな間違いは検出できて、どんな間違いは検出できないのか、とか、そういう事が当然問題になります。この、どれくらいの割合で誤りを検出できるのかという性能指標を「誤り検出率」といいます。誤り検出率100%といえば、どこをどんなふうに間違えても必ず検出できるということです。
(前回から符号、符号と言っていますが、簡単には、生のデータをいじって若干の情報変更を加えることを”符号化する”という風に理解しておけばいいと思います。11桁が生データで、誤り検出機能を持たせるために下1桁に適切な数字を付けるという”符号化”を行っているのです。)

どんな間違いでも必ず誤りを検出できる(ランダムエラーに対する誤り検出率100%と言います)というのは素晴らしいことですが、なかなかそう上手くはいきません。もちろん、付与する情報量(桁数)を増やせばできるでしょうが、桁数を増やしすぎても煩雑になります。付与する余分な桁数はできるだけ少なくして、それでいて如何に誤り検出率を上げるか、それが符号設計者の腕の見せ所なのです。モジュラス11の場合は、付与する桁数は1つだけと、始めから決めているんですね。

如何に誤り検出率を上げるか、と言いましたが、いきなりランダムエラーを考慮の対象にしたのでは範囲が広過ぎて難しいです。そこで、「発生しやすいエラー」に着目して、そういうエラーの検出率を上げることを重点的に考えるのが上手なやり方、ということになります。で、数字の羅列を扱う場合、この「発生しやすいエラー」として挙げられるのが、以下のようなものです。

(1) トランスクリプションエラー

  数字の書き間違い。12345 → 12845 など。

(2) トランスポジションエラー

  2つの数字の入れ違い。12345 → 13245 など。

(3) ダブルトランスポジションエラー

  間に1桁おいた2つの数字の入れ違い。12345 → 14325 など。

確かに、(2)はよくやりそうですね。さらにこれらのエラーが同時に何個起こるか、例えば、(1)の数字の書き間違いも同時に2つ、3つやってしまう場合も考えられますが(バカですけど)、それについては私自身が検証しきれてないので置いといて、各エラーを1つだけやってしまった場合のエラー検出率については、モジュラス11ウェイト2~7は結構優秀で、(1), (2), (3) の場合全て検出率100%だそうです。ただし、前回の(方式A)の場合です。ランダムエラーに対するエラー検出率は91%と言っている資料もありますが、確かめてないので知りません(計算にはかなり骨が折れそうです。こういう計算をサクッとやってしまうのが天才君なのでしょう。ハミング距離とか使ってできるのかな?よく知りません)。モジュラス11はモジュラス10に比べて検出率がかなり高いようです。

で、上の(1)~(3)について、方式Aの場合とBの場合とでエラーの検出具合がどうなるか、ちょっと具体的に確かめてみましょう。

(1) トランスクリプションエラーの検出率

マイナンバー12桁を扱う時に一カ所だけ上記のエラーを犯してしまった場合に、C/Dを使ってそれを検出できるかどうか、みてみましょう。

マイナンバーについて、C/D 部分の値をP0、C/D以外の部分については定義どおりに下位桁の数字から順番に Pn と書くことにします。また、C/Dの計算時に Pn に掛け合わせる重みの値は Qn でした。この時当然、1 ≦ n ≦ 11 となります。

今、 本来は値が a である P0またはPn を、間違えて b と書いてしまったとしましょう(もちろん、他の桁は間違えてないことが前提)。このエラーを検出できるかどうか、調べてみます。

(a) P0を間違えた場合

C/Dの値を勝手に変えてしまったのですから、確実に検出できますね。これ以上考えることはありません。方式AでもBでも同じです。

(b) Pn (1 ≦ n ≦ 11)を間違えた場合

この間違いがC/Dの値にどう影響するかを見てみればよいのです。メンドクサイのでC/Dの計算式の Σ Pn×Qn の部分を単に Σ と書くことにすると、上記の間違いによって Σの値は Qn (b - a) だけ変化します。いいですね。積和の部分の他の項の値は変わりませんから、引き算すると消えますよ。で、考えたいことは、 Σ の部分を11で割った余りが変わるかどうか、です。順を追ってみてみましょう。

定義から、Qn は2以上7以下の自然数です。また、b - a は -9 以上 9以下の整数で0を含みません(0だと間違えたことにならない。当然 a ≠ b の場合を考えていますから)。いいですよね。9を0と間違えてしまった場合に一番減って(-9)、0を9と間違えた場合に一番増える(9)わけです。

そうすると、Qn (b - a) について何が言えますか?よく考えてみてください。。。そう、これは、マイナスの符号も含めて「11の倍数ではない」ことが言えますよね。だって、11は素数ですから、その11の倍数を、11より小さいQn という自然数と、b - a という絶対値が11より小さい、そして0でもない整数、との積として表すことなんてできないはずです。分かりますよね。要するに素数11の倍数を、絶対値が11より小さい整数のみの積として表すことなんてできない、ということです。素数11の倍数は(0を除いて)素因数分解したとき必ず素因数11を含むはずですよね。

はい、Qn (b -a ) は11の倍数ではないことが分かりました。もちろん0でもありません。すなわち、Σの変化分を ΔΣ と書く事にすると、ΔΣ = Qn (b - a) は11の倍数ではないということです。ということは、「Σを11で割った余りの変化分」はどうなるでしょうか?そうですね、0ではないということが言えますよね。余りがズレないのは値が11の倍数ずれた場合”だけ”ですから、値のズレが11の倍数じゃないということは、11で割った余りは必ずもとの値からズレてしまうということです。

すなわち「Σを11で割った余りはこのエラーによって必ず変化する」ということが言えます(当然、Σを11で割った余りを11から引いた値もこのエラーによって必ず変化します)。さあ、このとき、C/Dはどうなるでしょうか?ここで、方式AとBとで事情が異なってきます。

方式Aの場合、Σを11で割った余り(メンドウなので Σ % 11と書きます)の、全ての異なる値に対して異なる扱いをしています。この値が1なら廃棄するし、0ならC/Dを0にするし、あとは、この値の11の補数(11 - Σ % 11)を C/D に採用しています。この補数の中に0はありません。なので、方式Aの場合、今回のエラーによって C/D の値が必ず変化するか、Σ % 11 の値が1になって”廃棄しなければならない番号だ、おかしいぞ”ということになるわけです。つまり、エラーを見逃してしまうようなことは絶対起こらない!のです。はい、誤り検出率 100% だと言えました。

一方、マイナンバーに実際に採用されている方式Bはどうでしょうか?方式BがAと違うところは、Σ % 11の値が0の場合と1の場合で同じ扱い(C/D = 0)をしている点です。これを考えると、方式Bの場合は今回のエラーを「場合によっては見逃してしまう」ことは、すぐに分かるでしょう。だって、たとえΣ % 11の値が必ず変化すると言っても、

・元々の Σ % 11の値が0(1)だったのが、エラーによって1(0)に変化した場合

のように変化した場合は、C/Dは結局0のまま変化しないということになりますから。つまり、方式Bは、一カ所のトランスクリプションエラーの検出率は100% ではない、ということが分かります(具体的に何% になるかは、頑張って計算すれば出るでしょうが、そこまでやるほど暇じゃありません。暇な人はトライしてみて下さい)。

具体的な例を挙げてみましょう。簡単です。上記ケースに当てはまる場合を適当に探せばいいんです。

000000110000 ( Σ % 11 = (5x1 + 6x1) % 11 = 0 なので C/D = 0)



000000310000

と一カ所書き間違えてしまった場合、Σ % 11 = (5x1 + 6x3) % 11 = 1 なので C/D は0のままとなり、元の正しい場合の C/D と変わりません。なので、1 を 3に書き間違えたエラーを検出できないですね。方式Aの場合だと、上記の値が1になってしまって、「00000031000などという、本来欠番の11桁の数字が使われるはずがない、どこかで間違っているはずだ」と、ちゃんと分かります。

疲れましたか? (2) のトランスポジションエラー、(3) のダブルトランスポジションエラーについても、同じように考えることができます。簡単に触れておきます。

(2)については、Pn = a, Pn+1 = b を入れ違えたと考えると、

ΔΣ = (Qn+1 - Qn) (b - a) となり、Qn+1 - Qn の部分は基本的に 1、n = 6 のときだけ -5 となります。 P0 =a と P1 = b を入れ違えた場合については、P1 を b から a に書き間違えた (1) のトランスクリプションエラーに含まれるので考えなくてよいです。方式Aだと検出率100%になるのは(1)と同じ理屈です。方式Bだと100%にならないことも、相互に区別できない以下のような例から分かります。

000000100110(Σ % 11 = (2x1 + 3x1 + 6x1) % 11 = 0 -> C/D = 0)
000000101010(Σ % 11 = (2x1 + 4x1 + 6x1) % 11 = 1 -> C/D = 0)

(3)については、Pn = a, Pn+2 = b を入れ違えたと考えて、

ΔΣ = (Qn+2 - Qn) (b - a) となり、Qn+2 - Qn の部分は 2, -4 の場合があります。P0 とP2 を入れ違えた場合については、P2のトランスクリプションエラーに含まれます。これも同じ理屈から方式Aだと検出率100%だし、方式Bだと100%にならないことも以下のような相互区別できない例から分かります。

000001107100(Σ % 11 = (3x1 + 4x7 + 6x1 + 7x1) % 11 = 44 % 11 = 0 -> C/D = 0)
000001701100(Σ % 11 = (3x1 + 4x1 + 6x7 + 7x1) % 11 = 56 % 11 = 1 -> C/D = 0)

さて、そろそろまとめたいのですが、方式Aだと折角 (1) ~ (3) のタイプの1個のエラーについて検出率100%なのに、どうしてわざわざ検出率が落ちる方式Bになっているのか、というのが、私が抱いた疑問でした。

で、1つ想像できることとして、方式Aの場合は「上位11桁部分でも欠番がでる」ことが大きな問題になるのではないか?ということです。復習ですが、マイナンバーの上位11桁の部分は、11桁の住民票コードをつかって”生成”されます。11桁の住民票コード自体の作り方は公開されていますが、この、住民票コードからマイナンバーの11桁部分を作る方法については公開されていないようです。ただ、マイナンバーの11桁から11桁の住民票コードを復元できないようにしている、ということは言われているので、住民票コードをそのまま持ってきているわけではないようです。何かしらの演算処理が行われているのです。

仮に、この演算処理の結果、先に「Σ % 11」と書いた部分の値を1にする11桁の数字がどうしても出現してしまうのだとしたら、、、方式Aは使えないですよね。マイナンバーを付与できない人が出て来てしまいます。「お前のマイナンバー、なし」というわけにはいかないじゃないですか。だから、符号の性能が少々さがっても、方式Bを採用せざるを得ない、ということなのかなーと想像するわけです。もちろん、何も公開されていないので真実はしりませんよ。あくまで想像です。

マイナンバー1つとっても、色々と頭の体操ができるわけです。









この記事についてブログを書く
« マイナンバー (2) | トップ | ”思考”でもなく”暗記”でもなく »