マイナンバー(もどき)を大量生成?

Ruby - マイナンバーのチェックデジットを計算する - Qiita

何となく気になって、チェックディジット(デジット、サム)(※1)の計算方法を調べてみたんだけど、要するにこれを使えば「無意味な11桁の数字」からマイナンバールールに適合するのが作れるということになる。

ということで、上記記事にあったコードを弄ってみた。

def create_my_number(dmynum)
  digits = ("%11d" % dmynum.to_i).chars.map(&:to_i)
  raise "#{dmynum}" unless digits.length == 11

  digits.reverse!

  remainder =  (1..11).inject(0) {|sum, i|
    p = digits[i-1]
    q = (i <= 6) ? i+1 : i-5
    sum + p*q
  } % 11
  case remainder
    when 0,1
      check_digit = 0
    else
      check_digit = (11 - remainder)
  end

  %Q!#{"%011d" % dmynum.to_i}#{check_digit}!
end
rng = Random.new()
1000.times do
  puts create_my_number(rng.rand(10**11))
end

もちろん、実際には上記記事にあるように「住民票コードから片方向の変換によって生成」されるから、デタラメに計算した数字が正しいマイナンバーになるわけじゃない。

でも、有効桁が11=1000億(※2)なのだから、確率的には1000個作れば1個ぐらいは誰かのマイナンバーに偶然一致する(※3)。

だからといって「ハッキングだ!」「脅威だ!」「マイナンバーの不正収集だ!」なんてことはない。

だって、狙って誰かのマイナンバーを(公にされてる情報から)作れるとかじゃなくて、何処の誰だか分からない人の番号に偶然一致するだけだから。

  1. ※1:表記ゆれ以外に、厳密にはcheckdigitとchecksumは違う。でもどちらも「符号が誤ってないか検出するための何か」である点は同じ
  2. ※2:424242424241(チェックディジット込み)のような番号を除外しないとして
  3. ※3:住民票コード→マイナンバーの変換に偏りがないと仮定した場合