Tukubaiマイナンバー。それは12桁の数字で表現されるシークレットなアイデンティティ・・・アイデンティティがシークレットとはこれいかに???これはTwitterでリプライをいただきながら進化していった物語である。Twitterでリプライしていただいた皆様、本当に感謝!ということで、少し前にマイナンバーをひたすら列挙するシェル芸の話題が上がっていた。これは、純粋に0から9までの数字を12桁並べるという単純なものだった。togetter.com最近、どこかは忘れてしまったが「マイナンバーシェル芸はチェックデジットを考慮されてないやんけ」、というツッコミが目にとまった。チェックデジットって何?ってことでググると下記のページが見つかった。qiita.comRubyを使って、チェックデジットを計算。不正なマイナンバーがどうかを判定いている。他の言語でも、このページを参考にしてチェックデジットの計算をされているようだ。12桁目の数字がチェックデジットってやつなのか。上記のページを参考にして、チェックデジットが適正なマイナンバーの一覧を出してみようか。シェルのワンライナー一撃で。YosemiteHomebrewでGNU系ツールとmawkを導入Linuxな人は、gseqをseqに、gsedをsedに、gheadはheadに読み替えること。考え方その1チェックデジットに適合したマイナンバーを列挙することを考える。最初は下記の処理を考えた。注意点ここに出てくるワンライナーは負荷が高い。Ctrl-Cなどで止める、もしくはプロセスの止め方を確認しておくことを忘れずに。ワンライナー作成では真のマイナンバーを列挙するワンライナーを作ろう。12桁の数字を1桁ずつ空白で区切ったものを作成。それをmawkに渡してチェックデジットの計算をする方針で。/g'とやっていたが、ここがどうしてもボトルネックになってしまう。いうことでTwitteで助けを求めてみた。みたいに空白で分離を高速に処理する方法。2016年5月1日するとリプライが。意味が分からなかったのでおたずねするとリプライが。再構築しているのです。2016年5月1日どのくらい処理速度が変わるかためしてみた。1000万行分の処理で計測。sedを使うより大幅な高速化が出来た。いうことで、真のマイナンバーを列挙するワンライナーがこちら。GNUのseqとmawkコマンドを利用。パイプでつなぐコマンドの数は減らせるが、わかりやすさ重視で。'000000000000000000000019000000000027000000000035000000000043000000000051000000000060000000000078000000000086000000000094....最初のgseqで12桁の数値を連続列挙。それをmawkに渡して、チェックデジットの計算と適合した行のみ抜き出す処理をしている。実はこの記事、Twitterで@ebanさんから指摘されるまで、チェックデジットの計算を間違っていたのだ。短くて高速な書き方のリプライが。@papiron1つにまとめるとこんな感じですね。2016年5月1日ただ、{アクション}の後ろに$12==(c<=1?0:(11-c))書かれている意味が分からん・・・ナニコレ??リプライで意味を教えていただいた。アクションと次のパターン$12==(c<=1?0:(11-c))は別物です。真になれば$0がprintされます。2016年5月2日そして更なる高速化が。ワンランナーも超シンプルに。FS=考え方その2しかしその後、Twitterでこんなリプライが。なんで指摘されるまで気が付かなかったのか???更なる飛躍的な高速化が期待出来るではないか。2016年5月3日ということで新しい考え方がこちら。処理するデータ量が10分の1になるね。11桁の数字を順に列挙するチェックデジットを計算12桁目に計算したチェックデジットを付加ワンライナー作成そして出来たワンライナーがこちら。なんだかとってもシンプルになった。FS=どのくらいの処理速度なのか?最初の1億人分の出力時間を計測。考え方その1に比べて約10倍近い速度になっている。0m3.472sオマケ1MacというかOSX標準装備のコマンドのみを利用したワンライナーがこちら。やっている内容は上記とほぼ同じ。処理速度はかなり遅くなる。Tukubaiが発売された。Open版に比べて処理速度が高速で、便利なコマンドが追加されている。Tukubaiのコマンドを使ったワンライナーがこちら。Tukubaiのコマンドは、yarr、loopx、lcalcだ。loopxとlcalcの高速さがポイント。'このくらい計算式が複雑になってくると、mawkとlcalcで処理速度はあまり変わらないようである。上記のように計算を2つに分ける場合はlcalcの方が並列化による速度向上効果が高かった。seqを使う方が処理速度が速い。-wオプションが遅くなる原因。0m1.592sこれは下記のTwtterつぶやきが参考になった。場合は特別に最適化したコードが選択されるようになっていますね。数値を+1して文字列化するのでなく、文字列を直接操作していたり。2016年2月22日おまけ4@ebanさんと@kunst1080さんから下記のリプライをいただいた。チェックデジットの計算をawkのforループを使って計算する方法だ。この方が数式の表現により近い計算方法になる。この方法を適用してみたところ、速度が倍以上遅くなってしまった。forループなどの処理が速度面でボトルネックになってしまったのだろう。今回の場合はベタに数式を書いた方が処理が高速になった。2016年5月3日ぱぴろん氏がチェックディジット計算を最適化しようとしているみたいなので、文字列を分割せずに計算する方法はないかなぁと思ってちょっと遊んでみたの図。2016年5月1日@kunst1080さんからリプライいただいた方法の場合は、下記のように最初にsum=0を追加して毎行sumを初期化しておこう。cd}'そして並列化へいろいろとやっていると、この記事のブコメに上田さんから並列化〜というコメントが。ああそうか並列化出来ちゃうね。ワンライナーは辛かったので、Gistにバックグラウンドで並列化するシェルスクリプトを載せておいた。パソコンに高負荷がかかり、危険を伴うので注意して実行すべし。バックグラウンド処理の速度計測するため、グループ化とかwaitとかを使っている。seqとmawkを使った場合で、xargsの-Pオプションを使った並列化についてリプライをいただいた。2016年5月6日おおお、結局ワンライナーで10並列書けたぞ。梅雨なのにあんまり雨が降らずこれはアカンと思う今日この頃。起きるとそこは雪国だった。はてなブログPro情報処理ってもっとシンプルにならないだろうか?PKI関連、RubyやPHP等のLL、シェルスクリプト、シェル芸、ユニケージ見習い未満。シェルスクリプトとシェル芸はきっと違うんですよ。JPはてなブログをはじめよう!papiroさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。