SVX日記
2005-03-02(Wed) ケタ違いに便利なメソッドを追加する
一昨日の電卓ネタにちょっと関連するお話をしてみたい。ここんトコ、NHKがかなりのバッシングを受けており、受信料の未払い騒動にまで発展しているらしい。まぁ、その後の対応が最悪だったとはいえ、会社の金の横領程度のコトはどこの会社でも起こるコトだからして、そんなコトを理由に受信料の支払いをヤメるなんて、どうかしてんじゃないの? ……と、一度として受信料を払ってないオイラがしみじみ思う今日この頃である。えー、よろしければスクランブルをおかけいただいてもけっこうでございますので。
ニュースによると、受信料収入が約72億円の減収となったので、全職員約1万2千人の給与、ひとり当たり年約23.3万円の減俸を行うコトに決定したらしい。減俸ってーと、なんか職員が悪いコトをしたみたいだが、ほとんど全員の職員がトバッチリなんだよな。気の毒だ。それはそうと、この減俸によって減収のどの程度が賄われるのだろうか。そこまで記事に書いてないので、計算してみるコトにした。
p 233000 * 12000
2796000000
ちゅーか、ゼロが多すぎてワカラン。そうなのだ、今日の日記のテーマは「位取り」なのである。そもそも、デカい金額は8桁しかない電卓では計算できない。位取りくらい人間がやればイイという意見もあろうが、もしそこを間違えた場合はとっても丸紅なのである。やっぱり機械にやらせるのが一番だ。
ところが、C言語なんかだと素直に32bitで表現できるのは、43億チョイに過ぎない。フツーは負数も考慮するから、21億。上記の28億という数字はヒト筋縄には扱えないのである。そんじゃ、物理的な桁制限のないRubyを使えばイイじゃないか、という意見もあろうが27960000などと表示されても困るのである。そらみろ、んなコトいってるソバからゼロがふたつも抜けてしまったではないか。
んじゃ、どうするか。Rubyじゃダメだと言った矢先ではあるが、やっぱりリングの王者はRubyなのである。Integerクラスにドドーンとこのようなアホなメソッド群を追加してしまうのだ。するとなんと!! こんな式が書けるようになってしまう。
p (23.man + 3.sen).kakeru(1.man + 2.sen).wa?
"27.oku 9600.man 0000"
わぉ。わかりやすい。記述にも無理がない(ホントか?)。メソッド名があまりにベタで、しかも「wa?」に至ってはたぶんコード標準に違反してしまっているし、コードの59行目に至ってはギャグタッチでさえあるが、便利なコトに変わりないだろう。調子に乗って、わが国の今年の見込み税収額の44兆0410億円を、総人口の1億2761万9千人で割って、国民ひとり当たりの税額を求めてみる。フツーならこんな感じに計算せねばならんが、
p 44041000000000 / 127619000
345097
p (44.cyo + 410.oku).waru(1.oku + 2761.man + 9.sen).wa?
"34.man 5097"
まぁ、このよーにデカい数字を日常的にガリガリ使うヒトがどれだけいるかはともかく、電卓に「単位ボタン」を装備するのも悪くないアイデアだと思う。「万ボタン」「億ボタン」「兆ボタン」の3つを設けてもいいし「単位ボタン」のひとつでもいいだろう。入力時に単位ボタンを押すと位がヒトツ上がるのだ。ちなみにこの「単位ボタン」は桁のカンマ区切りの数の変更キーとしても作用するようにしてしまおう。
2010-03-02(Tue) 来る日も来る日も「メーラを作る」
昨日、テキストベースのメーラ「Mave」のバージョン2.96をリリースした。添付ファイルが扱えるようになった。
オイラは、かねてより「添付ファイル」の扱い、大きくは「ファイルシステム」という概念そのものに大きな不満を感じており、今回の「Mave」には、自分なりに「ファイルシステムかくあるべき」という思想を込めた機能を実装したつもりである。誰も、ファイルを探し回りたくなんかないし、ファイル名を付ける際に考え込みたくなんかないのである。ましてや、ディレクトリというダンジョンで迷子になってTABキーを連打したり、.bak、.bak2、.bak3、.recent、.last、.finalなんて連中に囲い込まれるなんぞ、ウンザリなのである。この件については、そのうち改めて書こうと思う。
2011-03-02(Wed) ソウルをルビーで語る
$ vi ma3.rb
#!/usr/bin/ruby
ep = 8
system('/usr/bin/wget -O ch260.html http://ch.nicovideo.jp/channel/ch260')
movie_url = nil
open('ch260.html') {|fh|
fh.each {|l|
l =~ /href="([^"]+)"/ and movie_url = $1
l =~ /第#{ep}話/ and break
}
}
movie_url or raise('failed to get movie_url')
system("./nicovideo-dl -u mail@example.com -p password #{movie_url}")
movie_url =~ /(\d+)$/ and movie_file = $1 + '.mp4'
movie_file or raise('failed to get movie_file')
system("/usr/bin/ffmpeg -i %s -vcodec mpeg4 -s 320x240 -r 29.97 -b 600k -acodec libfaac -ac 2 -ar 44100 -ab 64k magicaPsp%02d.mp4" % [movie_file, ep])
$ crontab -e
0 5 * * 4 cd /home/mediasrv/magica; ./ma3.rb
2013-03-02(Sat) ひさびさダライアス
まずはダライアス。電源を入れた直後、右の画面が流れていたが、しばらくするとマトモに。エクストラバージョンだったが、ひさびさだったので、順当にA-B-D-G-K-Q-Vでストロングシェルを成敗。途中、赤も青も3〜4つずつ逃がし、何度もアームをはがされ、ヒヤヒヤのクリア。残アーム5枚。
元祖の怒IKARI。当時はあまり熱中しなかったが、最近になって無性にやりたくなってきた。ところが、電源を入れてプレイしようとしたが、スプライトがおかしく、自機も敵もマトモに見えない。さっさとゲームオーバーになってしまった。まぁ、骨董品だものなぁ。
2019-03-02(Sat) ピアノ調キーボード!?
先日、キーボードの黄ばみを漂白したのだが、実はそれはこの「ピアノ化」への前哨戦だったのであった。
もう軽く10年以上前にキーボードをピアノの鍵盤化するkonkというアプリを作り、何度か、何度か、何度か、一部のキーを黒鍵盤化してきたのだが、プラスチックを染められるというSDNという樹脂用の染料の存在を知り、あらためてガッツリと黒鍵盤化すべく、それを実行してみた。
対象であるキートップが冷えていると、投入時に染料の温度が下がるので、事前に紙コップの80度の白湯に漬けておく。あらためて、ナベに染料15gを投入、300gの水で薄め、80度まで加熱してから、網にキートップを投入、ナベの中の染料に漬ける。
ガシャガシャして、色の付き具合を確認して、を5〜6回繰り返す。ギリギリ、キートップの文字が見えるくらい、を目標にしつつ、あまり薄いのもつまらないし、と思いながら、適当と思われるタイミングで水洗い。作業完了。
2024-03-02(Sat) Sinatraでhtpasswd認証したりldap認証したり
回転のプログラミングの途中だが、ひょんなことから、Sinatraでウェブサービスを提供する各種のコンテナに認証機能を付ける必要が生じた。ハテ?基本的にはHAProxyを被せて運用しているのだが、認証ってどうすんだっけ?
use Rack::Auth::Basic do |username, password|
username == 'admin' && password == 'secret'
end
これを追加すると全体に認証がかかる。恐ろしいほどに見たまんまなコードだw。逆に言えば、ここに自分で仕組みを組み込んでやれば、好みの認証機能を実現できるということだ。ハッシュの知識はあるし、既にLDAPにアクセスするコードも持っている。ほんじゃ、ということで書いてみた。
require 'sinatra'
eval(File.read('pv/sinatra.config')) rescue true
@configs ||= {}
unless(@configs[:no_auth])
use Rack::Auth::Basic, 'Authorization Required' do |username, password|
authorized = false
if(@configs[:auth_htpasswd])
ht_password = false
open(@configs[:htpasswd_file]) {|fh|
fh.each {|l|
l =~ /^#{username}:(.+)/ and ht_password = $1 and break
}
}
if((it = ht_password) and it =~ /^{SHA}(.+)/i)
require 'digest/sha1'
hash_base64 = $1
hash = hash_base64.unpack('m*')[0]
challenge = Digest::SHA1.digest(password)
authorized |= (hash == challenge)
end
end
if(@configs[:auth_ldap])
require 'net/ldap'
ldap_password = false
ldap = Net::LDAP.new(
:host => @configs[:ldap_host],
:port => @configs[:ldap_port],
:auth => @configs[:ldap_auth],
)
results = ldap.search(
:base => @configs[:ldap_search_base],
:filter => '(cn=%s)' % username,
:attributes => ['userpassword'],
)
(it = results) and (it = it[0]) and (it = it[:userpassword]) and (it = it[0]) and ldap_password = it
if((it = ldap_password) and it =~ /^{SSHA}(.+)/i)
require 'digest/sha1'
hash_salt_base64 = $1
hash_salt = hash_salt_base64.unpack('m*')[0]
hash = hash_salt[0, 20]
salt = hash_salt[20, 4]
challenge = Digest::SHA1.digest(password + salt)
authorized |= (hash == challenge)
end
end
authorized
end
end
上記のコードをapp.rbの冒頭に追加すればいい。ApacheのhtpasswdとLDAPの両方に対応するが、今のところ前者は「{SHA}」後者は「{SSHA}」形式のみ対応。当初「$apr1$」形式に対応しようと思ったのだが、それは単なるMD5ではなく、どうもApacheの独自実装らしい。ソース読めばRubyで実装できなくはないが、そんなのに付き合っても今後とも得はなさそうなので「{SHA}」への対応にした。なので、htpasswdでハッシュを生成する際には-sを指定する必要がある。
どうでもいいが、Rubyのpack/unpackって、ホントに覚えられないなぁ。いつもpack/unpackのどっちが配列化/バイナリ化だっけ? ってなる。で、考えるもの面倒になって、適当にコードを書いて済ましちゃう。pack/unpackって、機能の格納方法としては天才的な発想だと思うけど、記述方法としてはどうなのよ……Perlが元祖なのかな。うーん……うううーん。
ま、それはそれとして、GitLabに置いてあるSinatraのスケルトンコンテナに上記のコードを組み込んで、とりあえずは作業完了である。
話は替わるが、だいぶ前から我が家では卓上カレンダを自作しているのだが、時期がきたので印刷したらグレートシングだった。え、もう2周もしたの? と思ったらそのとおりだった。うげぇ。エンジニアすぐ死ぬ。