jot
地区の回覧板に、『立川談志さんの落語の会』なんてご案内が載ってた。あれれ? 談志さんて もう他界しちゃってるよな、弟子が襲名でもしたんかな。いずれにせよ、参加無料、場所も家から 歩いて10分もかからない所。たまに馬鹿笑いするのもよかろうと思ったわけだ。
当日は朝から晴天、小春日和で散歩にはうってつけ。少し遠回りして行ってみた。座敷にお茶と 菓子と漬物とリンゴが用意されてた。地区のおばあさんが続々と集まって来る。男は主催者の 方を除いておいら一人。おまけに、座敷の床の間には、デンと大型ディスプレーが鎮座してる。
ああ、騙されたな。落語が大体朝の9時半から始まるなんて聞いた事ないぞ。密かに撤退しよう かと、思ったり思わなかったり。。そんなおいらの心情を察知してか、おそろいの派手なジャンバーを 着たおばさんが、目の前の茶碗にお茶をついでくれちゃったよ。こりゃ、撤退は諦めて、笑って 帰ろう、となっちゃいました。
開始まで少し時間が有ったので、ジャンパーのおばちゃんに聞いてみた。そのおそろいのジャンバー、 談志さんのファンクラブか何かのものですか? 我ながら変な質問だな。そしたら、そのおばちゃんは、 地区の保健婦さんなんですって。そうか、それで合点がいったよ。
家にいる老人をこういう催しにひっぱり出して、多いに笑ってもらおうって事なんだな。
隣に座ったおばちゃんに一応挨拶。農家の仕事(りんご、ぶどう、田)の仕事が一段落しつつ あるので、気晴らしに来たとか。おじいちゃん、おばあちゃんで農業が出来るのは、トラクター やら消毒車とかで力仕事をしなくてもいいからとか。その代わり、それらの機械の購入費やら 維持費が馬鹿にならないってぼやきも。。 息子が嫁でも貰って後を継いでくれればと、言って ましたよ。
演題は、寝床と権現狸の二題。落語って聴くものとばかり思っていたけど、観るものなんですね。 笑点しか見た事ないおいらは、認識を新たにしましたよ。
後で、主催者から挨拶があり、落語のCDはそこそこあるけど、視聴出来るDVDはほとんど無い 事を知った。演舞場まで気軽に行けない地方の方向けにいろいろリリースして欲しいぞ。 もう、韓流は止めにして。
shellで乱数生成
以前、freebsd-updateしてる時に待ち時間があったので、そのソースを見てた。面白い コードが出てたのでWebにも取り上げておいたけど、もちっと詳しく調べてみるか。 ちなみに、こんなコードだった。
# Generate a random seed for use in picking mirrors. If HTTP_PROXY # is set, this will be used to generate the seed; otherwise, the seed # will be random. if [ -n "${HTTP_PROXY}${http_proxy}" ]; then RANDVALUE=`sha256 -qs "${HTTP_PROXY}${http_proxy}" | tr -d 'a-f' | cut -c 1-9` else RANDVALUE=`jot -r 1 0 999999999` fi }
どこが面白い? Perlやrubyやpythonやlispなんて言うそれなりの言語処理系を使わなくても、 乱数を生成する方法が2種類、展示されているからだ。
一つは、sha256って言う何処にもありそうなコマンド。もう一つは*BSD限定(かも知れない)なjot ってコマンド。jotの方は、今回初めて知ったコマンドだけど、これがまた面白そうなんだな。 順番に見て行こう。
sha256
結城さんの『不思議な国のアリス・暗号編』だったかを見ると、きっと載ってるよ。 ネットからファイルをDLした時等、そのファイルが正統なものであるかどうかの検査に 使う。気の利いたサイト(セキュリティー意識の高い所)には、これの検査値が置いてある。
もっと身近な例だと、gitかな。リナス君が頑張って開発して、あれよあれよと言う間に野火の ごとく世界征服しちゃったね。このgitにも確か使われていたはず。
[sakae@secd ~/mruby/.git/objects]$ ls 55 70d35f9b2eff0741a5bec1e641349ac2cba189 feb645c2c973c3901a9a9e811921282121d02d
mrubyをgitからcloneしてきたけど、ファイルの実体は、こんな訳わかめな名前になってる。こんな訳わかめな名前を どうやって生成してるかと言うと、sha256なり(同属のsha1コマンド)で作っているんだ。ファイルの内容が一文字でも 異なると、この訳わかめな名前が大幅に異なったものになるんだ。いわゆる、ファイルの指紋って訳。
今回は、この訳わかめをsha256に生成させ、その中から不要なa-fを取り除き、残った数字だけを 冒頭から9文字抽出してる。
sha256にオプションを与えると、ファイルだけじゃなくて、指定した文字列からも指紋が 生成出来るんだ。
[sakae@secd ~]$ sha256 -qs hoge ecb666d778725ec97307044d642bf4d160aabb76f56c0069c71ea25b1e926825 [sakae@secd ~]$ sha256 -qs hogeX 46572136b70b7bd0575bd19b69d0f9839d42b0c6f35bbfa75afcc0c5ac814ed2
一文字違うだけで、指紋(ハッシュ値とも言う)は大幅に異なる。
[sakae@secd ~]$ sha256 -qs hoge ecb666d778725ec97307044d642bf4d160aabb76f56c0069c71ea25b1e926825 [sakae@secd ~]$ sha256 -qs hoge | tr -d 'a-f' 6667787259730704464241607656006971251926825 [sakae@secd ~]$ sha256 -qs hoge | tr -d 'a-f' | cut -c 1-9 666778725
上記は、hoge って文字列を種にして、9桁の乱数を生成する過程だ。unixの文字列処理コマンドと パイプを上手に組み合わせて、目的を達している。
それじゃ、使う度に違う乱数値を返すようにするには、どうしたらいいか? 使う度に違う値って 事なら、日時がいの一番にうかぶな。例えばこんなの。
[sakae@secd ~]$ date "+%Y%m%d%H%M.%S" 201210271324.20
これを種文字にしてもいいんだけど、もう少し味付けをしたい。塩を足すって意味でSaltを加える なんていいますけど、この塩には、よくpidが使われる。
[sakae@secd ~]$ date "+%Y%m%d%H%M.%S-$$" 201210271330.56-1081
後は、上記の味付け日時を種に使ってあげるだけ。
[sakae@secd ~]$ sha256 -qs `date "+%Y%m%d%H%M.%S-$$"` | tr -d 'a-f' | cut -c 1-9 866123124 [sakae@secd ~]$ sha256 -qs `date "+%Y%m%d%H%M.%S-$$"` | tr -d 'a-f' | cut -c 1-9 397674930
freebsd-updateの中では、種として、HTTP_PROXY(http_proxy)の設定値が使われている。 そんじゃ、もう一つのjotは、どうなっているんだろう?
jot
面倒なので、manから引き写します。(宿題だと落第だな)
NAME jot ? print sequential or random data SYNOPSIS jot [-cnr] [-b word] [-w word] [-s string] [-p precision] [reps [begin [end [s]]]] DESCRIPTION The jot utility is used to print out increasing, decreasing, random, or redundant data, usually numbers, one per line. The following options are available: -r Generate random data instead of the default sequential data.
実例をば、
[sakae@secd ~]$ jot -r 2 100 1000 857 195
これ、100から1000の間の乱数を2つ発生させなさいって指令です。もろに乱数発生器ですな。 でも、jotは説明にあるだけじゃなく、数列も発生できます。
[sakae@secd ~]$ jot 4 2 8 2 4 6 8
こちらは、2から8までの間を(等分にして)4つの数字を発生しなさいって事になります。うぃ、 こんなの、どこかで出くわした事あるよ。manをずっと辿って行くと、
The name jot derives in part from iota, a function in APL.
ほー、APLってIBMの数学研究所で生まれた高尚な言語じゃないですか。それにiotaって何処かで 聞いた事があるような。。。
HISTORY The jot utility first appeared in 4.2BSD.
カリフォーニアの大学の香りがしますなあ。例も載ってて、面白いなあと思ったのは、
[sakae@secd ~]$ jot -r -c 120 A Z | rs -g 0 5 | rs 0 8 XESMY VLMBO QIEEC CQZUK CIYIP OBGHN YERQR PLCBN RSWVW YYNXS XABWI QLJWS WUXOL PEWSF KJXGE UECIC UGCVD KMOUI GRDDG OTKLL PVUNC YIGAQ IVXLR AWDOQ
これ、前回やったモールス信号発生器の電文生成に使えるぞ。暗号の受信に最適。 意味は、AからZまでのASCII文字を120個発生しなさい。それをrsコマンドで受けて、5文字毎に 区切りなさい。それを8組並べなさい。行数は0って事で、この場合は制限無しって意味になります。
Linuxでも乱数
デフォでbashが入ってるはずだから、
[sakae@arch ~]$ echo $RANDOM 1200 [sakae@arch ~]$ echo $RANDOM 20047
こういう安易な方法でいいみたい。別な方法としては
[sakae@arch ~]$ od -vAn -N4 -tu4 < /dev/random 1680855093 [sakae@arch ~]$ od -vAn -N4 -tu4 < /dev/random 454376925
こういうのもあるそうです。デバイスに真の乱数発生器を接続すれば面白そう。だれか、ツェナーダイオードの アバランシュ効果(端的に言えば雑音)を使った発生器を作りませんかね。
Linuxで等差数列
Linuxには、高尚なjotコマンドは無いみたい。その代わり原始的なやつがある。
[sakae@arch ~]$ for i in `seq 1 4`; do echo $i; done 1 2 3 4
まあ、これで大概な用は足りると思うんだけど、jot を移植できないかな?
Linuxでもjotするぞ
FreeBSD側で、移植の前確認をしときます。まさか特殊な子分(ライブラリィー)は連れて いないよな。
[sakae@secd ~]$ ldd /usr/bin/jot /usr/bin/jot: libc.so.7 => /lib/libc.so.7 (0x2806a000)
大丈夫そうなので、ソース系を確認
[sakae@secd /usr/src/usr.bin/jot]$ ls Makefile jot.1 jot.c
Makefileを持って行ってもしょうがないので、jot.cとjot.1のマニュアルだな。 持って行ってコンパイルすると、
[sakae@arch z]$ cc -g jot.c jot.c:42:10: エラー: expected declaration specifiers or ‘...’ before string constant
// __FBSDID("$FreeBSD: releng/9.1/usr.bin/jot/jot.c 216370 2010-12-11 08:32:16Z joel $");
FreBSD特有のやつはお気に召さないようなので、コメントアウト
[sakae@arch z]$ cc -g jot.c /tmp/ccOuM4GL.o: In function `main': /home/sakae/z/jot.c:114: undefined reference to `strlcpy' /home/sakae/z/jot.c:293: undefined reference to `strlcpy' /home/sakae/z/jot.c:301: undefined reference to `arc4random' /tmp/ccOuM4GL.o: In function `getformat': /home/sakae/z/jot.c:410: undefined reference to `strlcpy' /home/sakae/z/jot.c:487: undefined reference to `strlcat' collect2: エラー: ld はステータス 1 で終了しました
strlcpyはFreeBSD特有っぽいので、strncpyに変える。(strlcatも同様)残るは、arc4randomだな。
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo-random num‐ bers in the range of 0 to (2**32)?1, and therefore has twice the range of rand(3) and random(3).
RSA社が作った暗号用の乱数発生器だ。jot.cの中では、
if (use_random) y = random() / divisor; else y = arc4random() / divisor;
こんな使い方をしてて、-rを付けた時にuse_randomがtrueになる。取りあえず、RSA社には遠慮 してもらったよ。久しぶりにclangに登場願って コンパイルしてみると、
[sakae@arch z]$ clang jot.c jot.c:114:48: warning: ordered comparison between pointer and integer ('char *' and 'unsigned int') if (strncpy(format, optarg, sizeof(format)) >= ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ jot.c:410:28: warning: ordered comparison between pointer and integer ('char *' and 'size_t' (aka 'unsigned int')) if (strncpy(p, "%c", sz) >= sz) ~~~~~~~~~~~~~~~~~~~~ ^ ~~ jot.c:487:46: warning: ordered comparison between pointer and integer ('char *' and 'unsigned int') if (strncat(format, "%", sizeof(format)) >= ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ 3 warnings generated.
イエローカードだから、取りあえず見なかった事にしよう。/usr/local系にmanも含めてインストール したよ。
[sakae@arch ~]$ jot 4 5 20 5 10 15 20 [sakae@arch ~]$ jot -wMyfile%04d.txt 4 4649 Myfile4649.txt Myfile4650.txt Myfile4651.txt Myfile4652.txt
ちゃんと動いているよ。(と言うと、testはどうしたって、目くじら立てる人が居るに決まってるな。)
iota
manにはjotの元になったのは、iotaって書いてあったな。 私のかすかな記憶では、iotaってSchemeのsrfi-1に有ったはず。確認してみる。
gosh> (use srfi-1) #<undef> gosh> (iota 10) (0 1 2 3 4 5 6 7 8 9)
どんなソースになってるかな? ~/Gauche-0.9.3.3/src/liblist.scmに有った。
(define (iota count :optional (start 0) (step 1)) ;srfi-1 (when (< count 0) (error "count must be nonnegative: " count)) (if (and (exact? start) (exact? step)) (do ([c count (- c 1)] [v (+ start (* (- count 1) step)) (- v step)] [r '() (cons v r)]) [(<= c 0) r]) ;; for inexact numbers, we use multiplication to avoid error accumulation. (do ([c count (- c 1)] [r '() (cons (+ start (* (- c 1) step)) r)]) [(<= c 0) r])))
これ、どう見たって、乱数の発生機能は組み込まれていないな。jotはiotaの進化系なんだな。
カンニングもとえ参照
上のiotaの一番簡単なのは、ただ個数を指定するだけ。Arch上に移植したjotでも動くんだろうな。 誰かさんに文句を言われないように、一番簡単なテストをしてみる。
[sakae@arch ~]$ jot usage: jot [-cnr] [-b word] [-w word] [-s string] [-p precision] [reps [begin [end [s]]]] [sakae@arch ~]$ jot 3 %.0-1f %.0-1f %.0-1f
引数無しで使い方ってのは想定内だけど、引数一つの結果がおかしいな。ちゃんとテストは やってみるもんだ。どんなテストをすればいいかってのは指針があるんですかね? 教えて、うるさいい 、もとえ、詳しい人。
で、エラーが見つかったら何とかせんといかん訳だが、もうソースと格闘する元気が ありません。何処かにLinuxへ移植済みのソースがないかな。 困った時はどらえもんを頼りにする、のび太君に変身しちゃえ。
ドラエモンのポケットと化しているウブでjotを探してみます。
sakae@ubuntu:~$ apt-cache search jot kjots - note-taking utility athena-jot - print out increasing, decreasing, random, or redundant data, one per line enum - seq- and jot-like enumerator gjots2 - Simple jotter (outline processor) for X11/gtk-gnome rhinote - virtual sticky-notes for your desktop
どうやら、athena-jotがそれっぽいので、お取り寄せ。一応コンパイルしてみます。
sakae@ubuntu:~/ubn-src/athena-jot-9.0$ make gcc -c -I. -g -O jot.c gcc -o jot jot.o -lbsd /usr/bin/ld: cannot find -lbsd collect2: ld returned 1 exit status make: *** [jot] Error 1
あらら、bsdのライブラリーが必要なのね。おいらが誤魔化しちゃったstrlcpyとかは、bsdライブラリーに 頼っているのね。しゃーない、開いてみるか。
あら、NetBSDからソースを持ってきているよ。冒頭付近
#if defined(HAVE_BSD_STDLIB_H) #include <bsd/stdlib.h> #define random arc4random #else #if !defined(HAVE_SRANDOM) || !defined(HAVE_SRANDOM) #if defined(HAVE_SRAND48) && defined(HAVE_LRAND48) #define srandom srand48 #define random lrand48 #else #define srandom srand #define random rand #endif #endif #endif /* HAVE_BSD_STDLIB_H */
ベタで書かれたプリプロセッサ命令は分かりずらいので、ちょっとインデントした。randomを どうするって話だけですな。
自動生成されたconfig.hを見ると、HAVE_BSD_STDLIB_Hなんて定義されていないのに、Makefileでは、 lbsdをリンクしろって指示してる。こりゃ、移植した人のやっつけ仕事だな。
手動でコンパイルしたら、普通に動いちゃったぞ。ソースの方では、strlcpy とかは使われていない。
結論的には、FreeBSDは独自の進化を遂げているんで、ソースをLinuxへ持ってこようとすると 苦労する。持ってくるなら、NetBSDのそれにしとけ。
ここからはおいらの想像だけど、はじめNetBSDな人がjotを書いた。セキュリティーに五月蝿い親分が いる、OpenBSDに取り込む時に、いろいろセキュリティー面を改良した。何でも貪欲に取り込む FreeBSD陣営が、OpenBSDの版を移植した。麗しきBSD3兄弟だなあ。
好きい夢 (Scheme)
少々疲れたので、夢でもみましょ。
以前やった、SimpleってSchemeが強力になってます。Windows上で強力に動くようにチューニング されてますので、もう鼻歌交じりでunix上に持ってくるのが辛くなりました。
今後は、 好きい夢 (Scheme)のサイトを 見守っていきます。とってもいい名前ですね。