先日、Windowsバッチファイルでチェックデジットを計算するプログラムを書きました。
Windowsバッチファイルでマイナンバーのチェックデジットを計算 - 沖の雑記帳
元の記事と同様に参照元は以下のQiitaの記事です。
でも、集計するならawkとか使ったほうが楽だよね。それにまだawk版はなさそうじゃん?ってことで書きました。
ただ、awkって実計算部分は他の言語と大差ないんだよね
なので今回は解説らしい解説も特には不要かな?
検証環境
awkで気をつけること
配列や、文字数の開始は1からで0ではないこと。この辺は他の言語と違っています。
変数は全てグローバル。関数や、各パターンマッチで同じ変数名使うと書き換わるよ。*1
パターンマッチした時の処理にnext
とか書いとかないと次に一致したパターンも延々処理していくよ。*2
と、こんなところでしょうか?
それでは続いてコードを貼り付けましょうね。
awkでマイナンバーのチェックデジット検証・集計
# サマリ出力するデータの初期化 BEGIN { invalid_count = 0 valid_count = 0 unexpected_count = 0 } # 全入力データを保存 { mynumber[FNR] = $0 } # 数値のみの行にマッチ /^[0-9]+$/ { sum = 0 if (length($0) == 12) { print "mynumber : " $0 digit = calc_checkdigit(substr($0,1,11)) print "digit : " digit if (digit == substr($0,12,1)) { print "validate : true" valid_count++ result[FNR] = 1 } else { print "validate : false" invalid_count++ result[FNR] = 0 } } else { print $0 " :requires 12-digit." unexpected_count++ } print "" next } # 非数を1つでも含む行にマッチ /[^0-9]+/ { print $0 " : Not be used non-numeric.\n" unexpected_count++ next } # どのパターンにもマッチしてこなかった場合は不正データ # 改行のみの場合などはここに来る { print "Unexpected data.\n" unexpected_count++ } # 検証結果のサマリ出力 END { print "Summary:" print " Number of data : " FNR print " Valid data : " valid_count for (i = 1; i <= FNR; i++) { if (result[i]) { print "\t" mynumber[i] } } print " Invalid data : " invalid_count print " Illegal data : " unexpected_count # 不正入力を出したい時だけ # for (i = 1; i <= FNR; i++) { # if (!result[i]) { # print "\t" mynumber[i] # } # } } # チェックデジットの計算 # 入力は11桁の数値列 function calc_checkdigit(number){ for (i = 1; i < 12; i++) { p = substr(number,12-i,1) if (i <= 6) { q = i + 1 } else { q = i - 5 } sum += p * q } remainder = sum % 11 if (remainder <= 1) { return 0 } else { return 11 - remainder } }
基本的にはコメントの通りです。
今回はそれぞれの入力に大してチェックデジットやtrue/falseなどを出力していますが、どちらかというと正しいものだけを抽出して出力したり表形式で正否を出力したりといった使い方の方が実用性があるでしょう。
一部を除いてほぼC言語なんかと変わらないですね。
以下検証関連
最後に入力データ数、チェック結果の数と、正しいデータのみを出力しています。
検証用データ
checkdata.txt
1234567890123 123456789010 123456789011 123456789012 123456789013 123456789014 123456789015 123456789016 123456789017 123456789018 123456789010 023456789013 1234567890 abcdefghijkl 12b45671b999 abcd111 486855818850 874413748700 700971250770 789947831400
検証結果
1234567890123 :requires 12-digit. mynumber : 123456789010 digit : 8 validate : false mynumber : 123456789011 digit : 8 validate : false mynumber : 123456789012 digit : 8 validate : false mynumber : 123456789013 digit : 8 validate : false mynumber : 123456789014 digit : 8 validate : false mynumber : 123456789015 digit : 8 validate : false mynumber : 123456789016 digit : 8 validate : false mynumber : 123456789017 digit : 8 validate : false mynumber : 123456789018 digit : 8 validate : true mynumber : 123456789010 digit : 8 validate : false mynumber : 023456789013 digit : 3 validate : true 1234567890 :requires 12-digit. Unexpected data. abcdefghijkl : Not be used non-numeric. 12b45671b999 : Not be used non-numeric. abcd111 : Not be used non-numeric. mynumber : 486855818850 digit : 0 validate : true mynumber : 874413748700 digit : 4 validate : false mynumber : 700971250770 digit : 3 validate : false mynumber : 789947831400 digit : 5 validate : false Summary: Number of data : 21 Valid data : 3 123456789018 023456789013 486855818850 Invalid data : 12 Illegal data : 6
需要あるかはわかりませんがプロジェクト
GitHub - okiworks/awk-mynumber: initial release
追記(2016-04-11)
このページも含めリンクしてくださっている、yumedotoさんのページリンクを追加
様々な言語での実装状況まとめも作成されています。