2011-12-27

メモリ増設後のテストは Memtest86+ のみでは不十分

先日メモリを増設したら、Memtest86+ は一晩中回してもパスするものの、実用するとランダムなプロセス (主な用途はネット閲覧用なので、Chrome のプロセスが多い) がクラッシュし、30分ほどで STOP エラー(ブルースクリーン) PAGE_FAULT_IN_NONPAGED_AREA, IRQL_­NOT_­LESS_­OR_­EQUAL などが出る不安定なマシンになりました。

状況から推測するにメモリの欠陥の可能性が大なのですが、Memtest86+ によるメモリのテストにパスすることで大いに困惑しました。Memtest86+ がよくテストしてくれるのは落ち着いたメモリアクセスでも発覚するメモリの物理構造上の欠陥であって、負荷がかかったときのアクセスタイミングの誤差のような微妙なところはカバーしないテストのようです(?)

結局のところオーバークロッカー御用達のメルセンヌ素数を素数判定することでメモリと CPU 全コアにストレスをかける Prime95 を走らせたところ、1秒で不合格になるので、Transcend の不良受付係に新しいのと交換してもらい、正常動作しました。

Prime95 にはメルセンヌ素数を探し続ける壮大な計画があるようですが負荷テスト用途にはユーザー登録しなくても使えます。

リンク
Memtest86+
Free Software - GIMPS - Prime95 の公式サイト
Prime95 Download - ComputerBase - 二次配布サイト

2011-12-25

[google] Spreadsheets API のカラム名正規化について

ドキュメントにはいまいち書かれていないようですが、1行を1レコードとして、それぞれの列の第1行のカラム名が付いた名前付きのレコードとして扱う list-based-feeds において、カラム名は以下のように正規化されます。hoge-foo-bar のようなハイフン区切りのカラム名もしくは camelCase にすると良さそうです。

foo123 -> foo123
123bar -> bar
foo_bar -> foobar
foo bar(間にスペース) -> foobar
foo-bar -> foo-bar (変化なし)
fooBar -> fooBar (変化なし)
foobar(2回目) -> foobar_2

参照
Google Spreadsheets API
- Developer's Guide (v3.0) - Working with list-based feeds

OAuth 2.0 Playground

[apache] mod_rewrite を使って拡張子を省略する

mod_rewriteを使って World Wide Web Consortium (W3C) のサイトのように .html を省略できるようにする方法についての記事です。

w3.org では、たとえば、
http://www.w3.org/TR/html5/introduction
http://www.w3.org/TR/html5/introduction.html
のように.htmlを省略できます。

これを mod_rewrite で実現するためには、以下のように RewriteCond で拡張子なしのリクエストを見極めて、RewriteRuleで /foo/bar -> /foo/bar.html に rewrite すればよいようです。
詳しくは公式ドキュメント mod_rewrite - Apache HTTP Server をご覧ください。

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} /[^./]+$
RewriteRule (.*) $1.html

補足
w3.org では mod_rewrite 方式ではなく、Content Negotiation が有効になっていることにより拡張子が省略できるようです。この機能はデフォルトでは有効になっておらず、以下のように有効化します。

Options +Multiviews

共有レンタルサーバーではほとんど使えるところはないかもしれません。デフォルトで有効となっていない理由はおそらくパフォーマンス劣化と非直観的動作なので、よく理解して利用すると良いと思います。

2011-12-23

Windows Installer に関する問題の修復ツールについて

Windows Installer はインストールに失敗した場合などシステムを壊さない方にロールバックしてくれますが、ごくまれに不完全なインストール状態に遷移する場合があり、いったんそうなるとインストールもアンインストールもできない困った状況に陥り大変困ります。

Microsoft もこの問題をよく認識しているらしく、強制的に問題のエントリを削除するツール Windows Installer Cleanup Utility (msicuu2.exe) をこのページで配布していたこともありました。
KB290301: How to uninstall or remove Microsoft Office 2010 suites

このソフトはインストール情報を Remove ボタン一つで壊すこともできる玄人仕様だったので、もう少し安全に配慮したアップデート版を、
診断ツール Fix it : 自動的にプログラムのインストールおよびアンインストールの問題を診断および修復する
こちらで配布しているので、これを使用すると良いようです。

この修復ツールの使い方は、基本的にはアンインストールの問題を選び、問題のソフトを選択します。ソフト名が出ていない不審なエントリ(数字とA-Fの長い文字列)も多くの場合はまずい動作を引き起こすようなので全てアンインストールの問題から選択して消せばよいです。このツールは通常のアンインストール動作に失敗すると、自動的に Windows Installer Cleanup Utility のような強制削除動作が行われるようです。

このツールが必要となるWindows Installerのエラーメッセージは、
  • 選択した機能は現在使用できないネットワークリソースにあります
  • 内部エラー 2711
  • 内部エラー 2753
などです。

2011-12-17

徳丸本プレゼント企画に当選しました

大変興味深いこちらの企画、徳丸本をブロガーに差し上げちゃうキャンペーンのお知らせ に応募させていただいたところ、本日当選のメールをいただきました!ありがとうございます。

当選したのはこちらの本です: 体系的に学ぶ 安全なWebアプリケーションの作り方
また感想も書く予定なのでよろしくお願いします。

リンク
徳丸浩の日記
ockeghem(徳丸浩)の日記
徳丸 浩 (ockeghem) は Twitter を利用しています
HASHコンサルティング株式会社

2011-12-09

[appengine] DeadlineExceededError には二種類ある

レスポンスが帰ってこないサイトに対して urlfetch.fetch をした場合などに発生する例外 DeadlineExceededError は、自分のレスポンスハンドラが制限時間を超過したときに発生させられる DeadlineExceededError と名前が同じように見えますが別のものになっています。

具体的には、urlfetchなど、API内で発生するのは、google.appengine.runtime.apiproxy_errors.DeadlineExceededError

自分のレスポンスハンドラが殺されたとき発生するのは、google.appengine.runtime.DeadlineExceededError

参考
python - Unable to handle DeadlineExceededError while using UrlFetch - Stack Overflow
svn/trunk/python/ google/appengine/runtime/__init__.py

2011-12-06

Google Libraries API はバージョンを指定して使う

jQuery など便利なライブラリを自分でサーバーを用意しなくても Google の CDN から利用可能なサービス Google Libraries API について、バージョンを厳密に指定せず自動的に最新版が降ってくるようにする指定方法には注意が必要です。

お勧めする方法
https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js

この時、Cache-Control の max-age は 1年間 になる。

お勧めしない方法1
https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js
https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js など

この時、Cache-Control の max-age は 1時間 になる。

max-age が短縮される理由は、1.7.x で自動的に最新バージョンが選択される仕組みにより、URL に対応する内容が変化しうるからです。

もしこの URL のキャッシュをブラウザはすでに持っていたとしても、取得から 1時間後以降はサーバーへのキャッシュバリデーションリクエストの返答を確認する必要があるので、即座にキャッシュを使う動作にならず、スクリプトが利用可能となるタイミングが少し遅れてしまいます。

@norahiko によると、自動的に最新バージョンを配信する仕組みがたまに上手く動いていないようなので。

お勧めしない方法2
http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js

http:// で取得されるファイルは安全であることが保障されない (通信経路で改ざんされる恐れがある) ので使わない方が良いです。もし仮に攻撃者のスクリプトが注入されれば Web サイト内の秘密は全て無くなります。

リンク
Google Libraries API

2011-12-03

[windows] 圧縮フォルダの関連付けを修復する

zipをフォルダのようにエクスプローラで見れなくなるなど、関連付けが壊れてしまったときは、こちらのサイトに置いてあるzip用のregファイルを取り込むと大抵元に戻るようです。

導入されるレジストリ断片は見たところ問題ないようですが、各自の責任の下で内容(テキスト形式なので読めます)をチェックしてください。

File association fixes for Windows Vista
File Association Fixes for Windows 7

Windows XPの場合は以下の手順で修復できるとのことです。
Q: CAB と ZIP を Windows 標準の関連付けに戻すには?

2011-11-20

開発用サーバー dev_appserver.py がデバッグログを出力しない

今まで home.py で logging.getLogger().setLevel(logging.DEBUG) とかやっていましたが、Python 2.7, webapp2, threadsafe: trueの環境に移行して、CGIモードではなくなって機能しなくなって困ったあげく、今さらながら解決策が分かりました。

開発用サーバー本体 dev_appserver.py のコマンドラインオプション一覧を見るとわかりますが、デフォルトがFalseとなっている '--debug' オプションを付けます。
これによりDEBUGレベルのログがちゃんと出るようになるので、app.yamlで制御されるディスパッチャの動作や、urlfetchの詳細なパラメータが出るようになるのでとても便利です。

Google App Engine Launcherを使っている場合は、プロジェクトごとのApplication SettingsでLaunch Settings, Extra Command Line Flagsに--debugを加えます。

2011-11-19

Accessing Spreadsheets API with OAuth2 + app_identity.get_access_token()

import pprint
import webapp2
import gdata.client
import gdata.gauth
import gdata.spreadsheets.client
from google.appengine.api import app_identity

pp = pprint.PrettyPrinter()

class GetWorksheetsHandler(webapp2.RequestHandler):
    def get(self):
        spreadsheet_key = self.request.get('key') or '0Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        scope = 'https://spreadsheets.google.com/feeds/'
        access_token, _ = app_identity.get_access_token(scope)

        oauth2token = gdata.gauth.OAuth2Token(
            client_id='',
            client_secret='',
            scope=scope,
            access_token=access_token,
            user_agent='your_application_name'
        )

        client = gdata.spreadsheets.client.SpreadsheetsClient()
        client = oauth2token.authorize(client)

        try:
            list = client.get_worksheets(spreadsheet_key=spreadsheet_key)
            self.response.out.write(str(list))

        except gdata.client.RequestError, msg:
            logging.debug(pp.pformat(msg))

application = webapp2.WSGIApplication([
    ('/get_worksheets', GetWorksheetsHandler),
], debug=True)

You need to copy
gdata-python-client's src/{gdata,atom} directories into your AppEngine project directory.

The client acts as the user 'APP_ID@appspot.gserviceaccount.com'. When you invite it as your collaborators, the application can modify your spreadsheet.

References
Getting started with python GData spreadsheets + OAuth2
Python gdata.spreadsheets.client get_worksheets
Google App Engine > App Identity Python API Overview

2011-11-15

[windows] Java Plug-In SSV Helper を削除するには

アンインストール後もIEのアドオンの管理にずっと残る迷惑なブラウザヘルパオブジェクトを削除するには、Sysinternals の大変すばらしいソフト Autoruns を使って、Internet Explorer タブの Browser Helper Object 項目内のエントリを削除します。

Java Plugin は、この他にも品質に疑問を感じる点 (javacpl.exe が管理者権限を要求せず設定が変更できないバグが1.6 update 29, 1.7 update 1 でも延々と放置されているなど) が見受けられるので、不要なマシン (Java での開発をしないマシン) からはアンインストールすることを強くお勧めします。

プラグインが存在しなければそもそも攻撃のしようがなく、うざったいアップデートに付き合わなくて済むので時間を節約でき、未知の脆弱性におびえる必要がなくなります。

参考
エフセキュアブログ : 有害とみなされるJava

2011-11-06

Canvasで三角関数を使わずに何とかする方法

JavaScriptでHTML5 Canvasを使っていて、円周上に点を書いてみたり、任意の角度で線を引きたい場合など、三角関数によってr, θからx, y座標を求めたくなる状況があると思います。

APIをよく見ると、三角関数は使わなくても、平行移動(translate), 回転(rotate)の座標変換を行えば、先のほとんどの状況で何とかなり、コードが大変すっきりします。

座標変換なんて事をすると元の座標系に戻れないんじゃないかと大変不安になられるかと思いますが、いったん状態をsaveした後、restoreすることで戻すことができるので気兼ねなくやってよいです。

参考
MDN - Canvas チュートリアル > 変形
HTML5 Clock - この時計アプリは三角関数を使用していません。

2011-11-03

Yahoo!おすすめ情報メールを一括解除するには

登録情報よりリンクされているこのページ
Yahoo! JAPAN からのおすすめ情報メール
から一括解除ができます。

注意
新しいサービスについて自動的に配信する設定になります。
配信されてくるメールからリンクされているページからは、そのメールでおすすめされるサービスの設定のみ変更できるので、一括解除は出来ません。

2011-09-26

[jquery] 複数の $.get が全部終わるまで待つには

jQuery を使って、リクエストを並列に送った後、すべてのレスポンスが出そろうまで待って処理をする、ということをやりたい場合は、jQuery.when() を使います。この関数を使うと、引数に与えた複数の Deferred オブジェクトから、新しく Deferred オブジェクトを作ってくれます。

jQuery 1.5 (2011/1/31リリース) 以降で利用可能です。

jQuery.get() の返り値 jqXHR は jQuery 1.5 以降では都合の良いことに Deferred になっているので、jQuery.when() にこれをそのまま渡せばよいです。

以下の例において、arg_a, arg_b は、もともとの Deferred の done の引数リストになっているので、jQuery.get() の、success(data, textStatus, jqXHR) の data を得るためには arg_a[0] 等とする必要があることに注意します。

$.when($.get('/path_a'), $.get('/path_b')).done(function(arg_a, arg_b) {
    var a_data = arg_a[0],
        b_data = arg_b[0];

    console.log([a_data, b_data]);
});

さらに、制限時間以内にレスポンスがそろわなかった場合に失敗とするには、以下のようにすれば良いです。

var timerDeferred = $.Deferred();

setTimeout(timerDeferred.reject, 1000);

$.when($.get('/path_a'), $.get('/path_b'), timerDeferred)
    .done(function(arg_a, arg_b) {
        var a_data = arg_a[0],
            b_data = arg_b[0];

        console.log([a_data, b_data]);
    })
    .fail(function() {
        console.log('fail');
    });

2011-09-19

Yahoo!ローカルサーチAPIで最速マクドナルド案内


Fastest fastfood

Yahoo!ローカルサーチAPI で最速マクドナルド案内を作ってみました。開くだけでGeolocation APIで取得した現在位置に基づいて、最寄りの結果を表示します。

結果の表示には最近リリースされた 経路地図API を使っています。

[javascript] Google 日本語入力 API を使って郵便番号から住所を取得

Google CGI API for Japanese Input を使うと JavaScript から Google 日本語入力の変換結果を取得できるようです。

NETBUFFALO さんの記事 によると、クロスドメイン対応は JSONP 形式のレスポンスに対応しているようなのでそれを用いました。jsonpというパラメータでコールバック関数名を指定します。

var postalcode = '150-0031';

$.get('http://www.google.com/transliterate?jsonp=?&' + $.param({
    langpair: 'ja-Hira|ja',
    text: postalcode
}), function (data) {
    if (data.length === 1) {
        var address = data[0][1][0];
        console.log(['solved', address]);
    } else {
        console.log('not found');
    }
}, 'jsonp');

参考
NETBUFFALO:Google日本語入力APIでAjax IME

関連情報
郵便番号から場所と関連情報を取得する「郵便番号API」公開しました! - お知らせ - Yahoo! Open Local Platform (YOLP)

2011-09-18

[python] urllib.urlencode の引数を全て encode('utf-8') する

リスト内包表現と、urllib.urlencode が2要素のタプルのシーケンスを受け入れることを利用しました。

#coding=utf-8
import urllib

param = {
    'name': u'なまえ',
    'msg': u'こんにちは!'
}
urllib.urlencode([ (k, v.encode('utf-8')) for k, v in param.iteritems() ])

[javascript] 一日後の Date オブジェクト

現在時刻から一定時間ずれた Date オブジェクトを作るには、以下のようにコンストラクタにミリ秒を与える方法で作れば簡単です。

new Date();
// Sun Sep 18 2011 12:40:50 GMT+0900 (Japan Standard Time)

new Date(+new Date() + 24 * 3600 * 1000);
// Mon Sep 19 2011 12:40:50 GMT+0900 (Japan Standard Time)

2011-09-16

[jquery] Google Chart Tools の QR Code機能を使う

簡単に使えて便利な、Google Visualization API の Google Chart Tools: Infographics: QR Code をjQueryを活用して楽しく使う方法についての記事です。

パラメータを静的に与えれば済む場合は、このサイト ChartTool で作ると便利です。

動的に与えたい場合、foo=bar&buzz=123&...と長々と手動で書くのはしんどいですが、以下のように、jQuery.param() を活用すれば楽しく使えます。

相対プロトコル指定にしてあるので、httpsのページでもいい感じに対応できます。

$('body').append($('<img />', {
    width: 80,
    height: 80,
    src: '//chart.googleapis.com/chart?' + $.param({
        cht: 'qr',
        chs: '80x80',
        choe: 'Shift_JIS',
        chl: 'あなたの予想に反してこのQR Codeが読み取れますか?'
    })
}));

表示例 (外枠はBloggerの側のスタイルです)

[jquery] append をもっと活用する

jQueryを使っているとわりと良くある状況:例えば、$.getで持ってきた情報に基づいて div#container にJavaScriptでp要素を追加する方法についてもっと考えてみます。

リストのそれぞれについてp要素を作って追加したい場合、ループ中でひとつひとつちまちまと append や appendTo で追記していく方法もありますが、配列演算と組み合わせられるようにするため、一気にやる方法について考えてみました。

appendのドキュメント を読むと、複数の引数をとることができるようなので、これを活用します。

// 1. よくあるコード
$('#container').append($('<p />').text('foo'));

// 2. jQuery(html, props) を使う
$('#container').append($('<p />', {text: 'foo'}));

// 3. append(content, content, ...) appendは複数個の引数をとることができます
$('#container').append(
    $('<p />', {text: 'foo'}),
    $('<p />', {text: 'bar'})
);

// 3a. 関数オブジェクトのメソッドapply(context, [arg1, arg2, ...]) を使って、配列でappendします。
// $.fn.append = $.prototype.appendです。
$.fn.append.apply($('#container'), [
    $('<p />', {text: 'foo'}),
    $('<p />', {text: 'bar'})
]);

// 3b. 配列を作る部分を $.map(list, fn)に置き換えます
$.fn.append.apply($('#container'), $.map(['foo', 'bar'], function (item) {
    return $('<p />', {text: item});
}));

// 4. もしくは、appendにelementArrayを与える方法
$('#container').append($.map(['foo', 'bar'], function (item) {
    return $('<p />', {text: item})[0];
}));

この方法を使えば、良くあるデータ構造(ハッシュのリスト) からの table の動的生成も以下のように簡単に書くことができます。

var $table = $('<table />'),
    list = [
        {
            name: '佐藤一郎',
            address: '東京都新宿区',
            tel: '0312341234'
        },
        {
            name: '山田太郎',
            address: '大阪府大阪市北区',
            tel: '0612341234'
        }
    ];

$table.append($('<tr />').append(
    $.map(['名前', '住所', '電話番号'], function (item) {
        return $('<th />', {text: item})[0];
    })
));

$table.append($.map(list, function (r) {
    return $('<tr />').append($.map([r.name, r.address, r.tel], function (item) {
        return $('<td />', {text: item})[0];
    }))[0];
}));

$('#container').append($table);

/*
<table>
<tr><th>名前</th> <th>住所</th> <th>電話番号</th></tr>
<tr><td>佐藤一郎</td> <td>東京都新宿区</td> <td>0312341234</td></tr>
<tr><td>山田太郎</td> <td>大阪府大阪市北区</td> <td>0612341234</td></tr>
</table>
*/

出力例
名前 住所 電話番号
佐藤一郎 東京都新宿区 0312341234
山田太郎 大阪府大阪市北区 0612341234
前回の jQuery の記事 [jquery] jQuery(html, props)が便利 もぜひ併せてご参照ください。

2011-08-15

[linux] shred でディレクトリを完全削除する

VPSを引っ越したり(通常盗み見できませんが念の為)、HDDを破棄する場合など、削除したつもりのファイルの内容を残したくない場合、shred(シュレッド?)を使うと、ファイルの内容を意味のないデータで上書きしつつ削除できます。今回はさらに、findを使ってディレクトリ内のファイルをすべて削除してみました。

shredが無いときは、ファイルを削除した後、ランダムデータを空き領域いっぱいに書き込む方式でも十分かもしれません。

OS XにはsrmというSecureなrmコマンドがあって、FreeBSDではrm -Pを使うと良いようです。

# 注意:TARGET_DIR内の全てのファイルが再帰的に削除されます
$ find TARGET_DIR -type f -print0 | xargs -0 shred --remove
$ rm -rf TARGET_DIR # ディレクトリが残っているので削除します

参考
DSAS開発者の部屋:shredのあれこれ

2011-08-04

Google Music Beta での文字化け回避方法 (foobar2000)

本日使い始めて気づいたのですが、音楽ファイルのアップロードに使用するクライアントの、ID3タグ中の日本語(Shift_JIS)の扱いに難があるようです。

クライアントは幸いにもUTF-8/UTF-16は理解してくれるので、ID3v2.4またはID3v2.3でUnicodeを使うように作り直すと上手くいきます。

ID3v1ではUnicodeは使われないみたいなので、削除した方が良いように思います。

ID3v2でも必ずしもUnicodeしかありえないかというとそうでもなく、Shift_JISが入っている場合もあるみたいです。

foobar2000では、Rebuild MP3 streamはタグを変更しないので、行ってもShift_JISのまま変化しません。Tag typeでID3v2.3→ID3v2.4の変更をするとついでにUnicodeになるようなので、この機能が使えます。このあとさらにID3v2.3に戻してもOKでした。
参考: foobar200 FAQ - MP3 tags (ID3v2) added or modified by foobar2000 are not read or are read improperly in application X or portable player Y. What can I do?
> foobar2000 writes ID3v2.4 tags encoded as UTF-8 by default.

Album ArtistはTPE2方式にのみ対応しているようなので、foobar2000の設定のAdvancedのところでTPE2方式を使うようにしてから、Album Artistの入っているファイルのタグを更新してください。

MusicManagerに更新日時の変化していないファイルのタグを再読み込みさせるにはServerDatabase.dbを削除します。

Windowsの場合は
C:\Users\_USERNAME_\AppData\Local\Google\MusicManager\ServerDatabase.db
SQLite Database Browser などで開いて、Table: XFILESを覗くとアップロード終了を待たずに文字化け状況が確認できます。

2011/08/05 8:21 追記
上手く読めないファイルのID3タグをダンプしてよく調べたところ、だいぶ間違っていたので修正しました。

2011-08-03

[gae] Google App Engine (Python) を始める人用 Tips

まず最初に読むべきところは、スタートガイド (いわゆるチュートリアル)
開発用サーバーでは、ファイルをいじってもサーバーを再起動する必要はなし。デプロイのコマンドは、appcfg.py update DIR
API リファレンスは英語版のみに情報がある場合あり Channel API, Receiving Email
実際に動くコードをもっと見たい人は、Google特製のサンプルコード集

JSON を扱うときは同梱されている simplejson を使う。

import simplejson
simplejson.dumps({'foo': u'あいう'}, ensure_ascii=False)

参考:After installing new SDK this : from django.utils import simplejson does work anymore

DEBUG ログが出るようにする方法と、PrettyPrinter を使ってネストしたデータを見る。

import logging, pprint

logging.getLogger().setLevel(logging.DEBUG)
pp = pprint.PrettyPrinter()

logging.debug(pp.pformat(['foo', {'bar': 'buzz'}]))

path のキャプチャの方法
class FooHandler(webapp.RequestHandler):
    def get(self, id):
        # /foo/123 へのリクエストなら、id = '123'

app = webapp.WSGIApplication([
    ('/foo/([0-9]+)', FooHandler), # 欲しいところを括弧しとく
], debug=True)

webapp.util.run_wsgi_app(app)

Windows の App Engine Launcher を使っていていちいちコマンドプロンプトが出てウザい:python.exe じゃなくて、pythonw.exe を指定すれば良い。

2011-08-02

[css] float や position:absolute についての詳しい資料

いくら検索しても、とりあえず目の前の仕事をこなそうという安直なサイトばかりが上位にヒットして、きちんと勉強できずイライラしている方も多いと思います。

そんな方には、W3C が公開している CSS2.1の仕様書 はいかがでしょうか。仕様書らしからぬヴィジュアルな例示が沢山あって、とても分かりやすく書かれています。

float や position はボックスの配置に関わるところなので、こちらのページに解説があります。 CSS2.1 Spec - Visual formatting model

勝手に要点をまとめると、
  1. float はマージンの相殺がどうなるかという点。
  2. position: absolute は、親要素であらかじめ意味なく position: relative しておくと、基準となる座標を選べる。
  3. その他:勉強中です。

2011-07-23

[anyevent] 設定ファイルを SIGHUP で再読み込みする

最近は新進気鋭の Web Application Framework: Amon2 にも倣って、設定ファイルはPerlでハッシュリファレンスを返すように書いて、それをdoするようにしていて、シンプルで良いなと思っています。

AE_PerlIsm では、さらにブラックリスト追加などをTwitterへのStreming APIの接続を切らずに対応できるように、以下のようにシグナルにコールバック関数を登録する AE::signal 'HUP', \&callback を使って好きな時点で読み込めるようにしてみました。

この変更により、たとえば無名関数で書いたスパム判定ロジックを本体が動作したままアップデートすることも可能になります。

$config 内で $config を参照するのは循環参照でリークして良くない例なので修正。

hogehoge.pl (本体)

use strict;
use warnings;
use AnyEvent;
use AnyEvent::Twitter::Stream;

my $config_filename = 'hogehoge.conf.pl';
my $config;

reload_config();
$config or die;

main_loop();

sub main_loop {
    my $reload_config_t = AE::signal HUP => \&reload_config;

    my $streamer = AnyEvent::Twitter::Stream->new(
        username => $config->{username},
        password => $config->{password},

        on_tweet => sub {
            my $tweet = shift;
            return if $config->{is_spam}->($config, $tweet);

            ...
        },
    );

    AE::cv->recv;
}

sub reload_config {
    warn "reload_config";

    my $config_tmp = do $config_filename;

    if (defined $config_tmp) {
        $config = $config_tmp;
        warn "$config_filename: successfully loaded";
    } else {
        warn "$config_filename: syntax error: $@" if $@;
        warn "$config_filename: error: $!" if $!;
    }
}

hogehoge.conf.pl (設定ファイル)

use strict;
use utf8;
my $config = {
    username => 'hogehoge',
    password => 'foobar123',

    blacklist => [
        1111111,
        2222222,
        qr!3333*!,
    ],

    is_spam => sub {
        my ($config, $tweet) = @_;

        return $tweet->{screen_name} =~ /^spam/
            or $tweet->{screen_name} eq $config->{username};
    },
};

[windows] Aeroが落ちて画面がしょぼくなった場合の対処法

Windows 7などを使っていて、ごくまれにAero(dwm.exe)が死んで透過表現が無くなり、見た目が急にしょぼくなったことはありませんか?基本的には自動的に再起動されるはずですが、手動でもファイル名を指定して実行から、dwm を起動すればすぐに元通りになります。お試しあれ!

また、自動的に問題を発見するツール「透明度やその他の視覚効果に関する問題の発見と解決」を実行することで解決の手助けになるかもしれません。コントロールパネルの検索で見つかります。

2011-07-19

[python] datetime から unix epoch を得る

Python 2.5 で、datetime から、JavaScript で使いやすいミリ秒で表した UNIX 時刻を作る方法を考えてみました。

# coding=utf-8
import time, calendar, datetime, pprint

def datetime_to_epoch_1(dt):
    return int(time.mktime(dt.timetuple())) * 1000 + int(dt.microsecond / 1e3)

def datetime_to_epoch_1_utc(dt):
    return int(calendar.timegm(dt.timetuple())) * 1000 + int(dt.microsecond / 1e3)

def datetime_to_epoch_2(dt):
    delta = dt - datetime.datetime.fromtimestamp(0)
    return delta.days * 86400000 + delta.seconds * 1000 + int(delta.microseconds / 1e3)

def datetime_to_epoch_2_utc(dt):
    delta = dt - datetime.datetime.utcfromtimestamp(0)
    return delta.days * 86400000 + delta.seconds * 1000 + int(delta.microseconds / 1e3)

pp = pprint.PrettyPrinter()
now_local = datetime.datetime.now()
now_utc = datetime.datetime.utcnow()

pp.pprint([
    datetime_to_epoch_1(now_local),
    datetime_to_epoch_2(now_local),
    datetime_to_epoch_1_utc(now_utc),
    datetime_to_epoch_2_utc(now_utc),
    time.time(),
])
# [1311003732034L,
#  1311003732034L,
#  1311003732034L,
#  1311003732034L,
#  1311003732.0339999]

2011-07-17

[Node.js] 続 /dev/urandom を延々と出力する HTTP サーバー

この記事は過去の記事 [Node.js] /dev/urandom を延々と出力する HTTP サーバー の続きです。

ドキュメントをよく読んでいたら、Readable Stream のインスタンスメソッド pipe を使うと簡単に書けることが分かりました。このメソッドは引数に Writable Stream を渡すと、drain を監視しながら少しずつ流し込む、過去の記事と同様の動作を勝手にやってくれる働き者です。

さらにこれと同様の動作をする util.pump というのもありますがお勧めしないとのことです。
参考: Difference stream.pipe and util.pump?

var fs = require('fs'),
    http = require('http'),
    PORT = 10001;

http.createServer(function (req, res) {
    var stream = fs.createReadStream('/dev/urandom');

    res.writeHead(200, {
        'Content-Type': 'application/octed-stream',
    });

    stream.pipe(res);

}).listen(PORT);

[perl] Imager で背景用タイル画像を動的に生成する

このブログをご覧の数少ない読者さんはもうご存知かもしれませんが、hidekiy.com の背景画像と配色その他を夏用にリニューアルしてみました。

ひとつ前のバージョンでは、Image::Imlib2 を使っていたのですが、HSV色空間への対応や、変数への書き出しのあたりがイマイチだと思っていたので、今回は新しく Imager を使ってみました。
$ cpanm Imager
で簡単にインストール出来る点と、丁寧なドキュメントを考慮すると、ImageMagickより良さそうな気がしました。

ソースコードは以下の通りです。

use strict;
use warnings;
use Imager;
use Plack::Request;

my $app = sub {
    my ($env) = @_;
    my $req = Plack::Request->new($env);

    my ($xsize, $ysize) = (60, 60);

    my $img = Imager->new(
        xsize => $xsize,
        ysize => $ysize,
    );

    $img->box(filled => 1, color => 'white');

    my $hue1 = rand(360);
    my $hue2 = $hue1 + 60;

    for my $i (0 .. 9) {
        my $color =  Imager::Color->new(
            hue => ($i % 2 ? $hue1 : $hue2),
            saturation => rand(0.1),
            value => 1,
        );

        $img->box(
            xmin => rand($xsize),
            ymin => rand($ysize),
            filled => 1,
            color => $color,
        );
    }

    my $data;
    $img->write(type => 'png', data => \$data);

    my $res = $req->new_response;
    $res->status(200);
    $res->content_type('image/png');
    $res->body([$data]);

    return $res->finalize;
};

出力例(60x60pxの画像を25個くっつけたもの)

動かし方: app.plで保存して、$ plackup app.pl

まず、$hue1, $hue2は、色相環で考えたときに60度離れた色相を2つ用意しています。
10回のループ中で、画像内のランダムな任意の一点から右下隅までを塗りつぶします。
塗りつぶすときの色は、用意した色相を交互に用いながら、彩度をランダムに変更することで、ちょっと色のくすみ方が変わります。

これをRGBで選ぶ方法でいい感じにするのは難しいので、HSV色空間を理解されると色指定が簡単になると思います。

[perl] 一部の CPAN モジュールに必要な devel パッケージ一覧

CPANモジュールをインストールしようとしても、エラーが出てインストールできないとき、そもそもCコンパイラが入っていなかったり、コンパイル時に必要となるヘッダファイル(hogehoge.h)が含まれている開発用パッケージ(foobar-devel)が入っていない場合があります。

ぜひこの記事を参考に、インストールはあっさり完了してしまって、速やかに本題に取り掛かかってください。

# 基本的に必要
yum install make gcc

# SSL
yum install openssl-devel
cpanm Net::SSLeay
cpanm LWP::Protocol::https

# 多倍長整数演算
yum install gmp-devel
cpanm Math::BigInt::GMP
cpanm Crypt::DH
cpanm Net::OpenID

# 多倍長整数演算
cpanm -v Math::Pari
最新のソースコードパッケージを自動で取ってくるかと聞くプロンプトには、'y'と答える
> Fetch? (y/n, press Enter) y

# XML
yum install libxml2-devel
cpanm XML::LibXML
cpanm Web::Scraper

# XML
yum install expat-devel
cpanm XML::Parser

# コンソールの制御用?
yum install readline-devel
cpanm Term::ReadLine::Gnu
cpanm Dvel::REPL

# JPEG
yum install libjpeg-devel
cpanm Imager::File::JPEG

# PNG
yum install libpng-devel
cpanm Imager::File::PNG

# 画像処理
yum install gd-devel
cpanm GD

# 圧縮
yum install zlib-devel
cpanm Compress::Zlib

見当たらない場合、ヘッダファイルの名前からパッケージを検索するには、yum providesを使います。Debian系なら、apt-file search です。

実行例:

$ yum provides '*/gmp.h'
Loaded plugins: fastestmirror, priorities, security
gmp-devel-4.3.1-7.10.amzn1.x86_64 : Development tools for the GNU MP arbitrary precision library
Repo        : amzn-main
Matched from:
Filename    : /usr/include/gmp.h

2011-07-08

Pyrit による解析から無線LANネットワークを守るには

Pyrit などによる総当たり攻撃から、個人用無線LANネットワークを守る方法についての記事です。

GIGAZINE さんの記事 無線LANの WPA / WPA2-PSK を GPU で超高速解析してパスワードを見つけるフリーのオープンソースソフト「Pyrit」 では対策の指針が示されていないので補足してみます。

簡単な対策法
暗号化方式として、WPA2-PSK (AES) を選択し、事前共有鍵 (PSK) として 63文字の鍵を設定します。鍵は安全な場所で管理してください。記憶する必要はありません。

詳細
SSID ステルス機能や、MAC アドレス限定接続機能、プライバシーセパレータなど子機間通信を制限する機能は、対策したような気分以外において全く意味がないので無視してよいです。WPA2-PSK において、攻撃者に対する唯一にして最大の抵抗策は、十分な強度の事前共有鍵 (PSK: Pre Shared Key) を設定することのみによってなされます。

そのような鍵の作り方は、手ごろな所で、OpenSSL 付属の openssl コマンドを rand オプションを付けて実行すれば、OS の乱数生成機由来の暗号学的に安全な乱数で作った文字列を取得できます。

$ openssl rand -base64 100
PyPTFpJyRrj94+AzhVKqs4ipUbZXJ7/RCefcAbk9mEiPr8H78tsVjUaLDOvT1OmP
QYkZGqdGfc2Ng0UmCZFFE4FgYuphU9uTb5hXzV5FM6vmbfi8cMmKC6aoCzDx7h01
KuFi9g==

出力はデフォルトではバイナリ列なので、-base64 オプションを追加して Base64 でエンコードしてみました。これを事前共有鍵の ASCII 指定での最大長63文字つかえば、6bit * 63 = 378bit となるので、最終的な 256bit の鍵を作るにあたっては十分な強度になっています。

OpenSSL を信用しない方は以下のようにしても良いです

$ head --bytes 100 < /dev/urandom | base64
w/I2+XY9Vymu8feYIbWn9T/L7yZk0ilfYObwoJDaRS3/FJ/0r5HSawyObGAG50aAcmr+Qqwh0D2x
SEIvwR/VM5bJRvpawoc0k9Fp6JV2igLhgFRqdSFXmMKxGSqNR5V7Sdtjpg==

Windows の方は PowerShell を使って以下のようにすると良いです

PS> $byteArray = New-Object Byte[] 100
$rngProvider = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$rngProvider.GetBytes($byteArray)
[System.Convert]::ToBase64String($byteArray)
/PppxyEFLAMlbr0WaIMSwFQ15RdtCIbZ3+csAYkVRuWwqX7nydT8/Rv6Trvan1O0p+HnPLJbF4k4SIEyjB3eMbiUie2aPNu0iT72bLbfZOoMgGTDkAJbmEj
86byd24vqXo9k6w==

64文字の16進数文字列で 256bit の鍵を直接指定する方法もありますが、アクセスポイント側の実装が怪しい場合があるようです。

注意
C言語のの rand() 関数などで作れる疑似乱数には、乱数種 (長く見積もって 64bit) 以上の乱雑さがないので、これに由来する鍵は使ってはいけません。参考: 擬似乱数

結論
辞書もしくは組み合わせ生成による総当たりで割られるような弱い鍵を使ってはいけません。暗号鍵の運用上の問題で、暗号そのものの持つ機能が発揮されないと、設計よりずっと弱い保護しかなされず、攻撃に敗れます。無線LANルーターはWPA2の次の仕様では、事前共有鍵として、20文字以下の短い鍵の使用を拒否するべきです。

毎秒数十万回?
毎秒100万回 (1e+6/s) は、毎年 3.15e+13 回で、鍵全体が 2^256 (PSK を ASCII で指定した場合、関数 PBKDF2 によって、256bit の鍵になります) = 1.16e+77 個分をこの速さで全体を調べるには 3.68e+63 年となり全然歯が立ちません。しかし、鍵が弱いことが分かっている場合 (小文字で8文字と分かっているなど) は、全範囲を調べる必要がなくなるので、現実的な時間で破られる場合があります。

アルファベット小文字で 8文字の鍵を全部調べるのにかかる時間を計算してみると 26^8 / 1e+6 / (3600*24) = 2.4日となり、全部調べる必要がある場合は最悪の場合で、半分調べれば鍵を見つける可能性が 50% になるので、平均 1.2日で破ることができます。

参考
The twilight of Wi-Fi Protected Access « Pyrit Pyrit作者の記事
WPA key calculation - From passphrase to hexadecimal key

2011/7/9 追記
GIGAZINE さんで記事が追加され、この記事が紹介されました。ありがとうございます。
無線LANのWPA/WPA2-PSKを総当たりで突破する「Pyrit」の実際の解析速度と自衛手段について

2012/3/16 追記
鍵の作り方について長らくめんどくさい方法を推薦していましたが、正直なところ、ごちゃごちゃっとキーボードを叩いて 63文字分の鍵を作ってもおそらく十分な強度があります。作った後適当に大文字にして数字や記号も散りばめておきましょう。

2012/12/14 追記
Pyrit のやっていることは結局のところ GPU Accelerated PBKDF2 ということになるので、ASCII で強い鍵が設定されていることが分かっているときは PBKDF2 のことは忘れて 256bit AES をそのまま破る方に尽力した方が速く破れると思います。

2011-06-28

[aws] EC2 で壊したインスタンスを修理するには

Amazon Web Services の EC2 では、仮想ローカルコンソール機能が無いみたいなので、起動しなくなるなど、SSH でアクセスできなくなるような壊し方をした場合、手詰まりになりそうになるので、そんな方を救済する方法についての記事です。

そういう時は、EBS にアクセスすることができるように同じ Availability Zone にもう一個、一時的にマイクロインスタンスを立ち上げて、壊したインスタンスの EBS を Web 上の AWS Management Console で、まずデタッチし、一時的なインスタンスにアタッチ、マウントして修理することができます。

アタッチ、デタッチなどは、AWS Management Console と称する AWS の Web 上の管理画面で可能なので簡単にできますが、頭の中が平常な時にあらかじめ練習しておいた方がいいと思います。

具体的な操作手順
  1. 壊したインスタンスをシャットダウンする。Shutdown Behavior の設定により Terminate されると一緒に EBS が削除されるので注意する。Stop なら削除されないので大丈夫。
  2. 壊したインスタンスに関連付いている EBS (※1) をデタッチする。どこからデタッチしたかメモを取る。例: /dev/sda1
  3. 一時的なインスタンスを同じアベイラビリティゾーンに立ち上げる。
  4. ※1 を一時的なインスタンスにアタッチする。
    たとえば: /dev/sdb
  5. ファイルシステムにマウントして、修理する。
    sudo mount /dev/sdb /mnt
  6. マウント解除する。
    umount /mnt
  7. デタッチして、壊したインスタンスの方に再度アタッチする
  8. 上手く動くようになればOKで、ダメなら再度アタッチ、マウントしていじってみる。
    備考: 修復はあきらめる場合でも、データは救出できます。

そもそも私はどう壊すに至ったか
Amazon Linux AMI で、あまりよく考えずに
sudo mv /etc/sudoers.rpmnew /etc/sudoers

したら、Enter を押してから気づいたのですが、sudoers.rpmnew はほとんど何も設定されていなかったので、即座に管理者権限を失いました。
sudoers をいじるときは、万一の事態を想定して、事前に su を使えるようにしたり、root shell を別に開いておくべきでした。

参考
Locked myself out of root account on EC2 Ubuntu instance

Amazon Linux AMI の yum-updatesd を機能させる

yum-updatesd が、デフォルトで常駐 (Amazon Linux AMI 2011.02 にて) していますが、何ら機能していないのでそれをどうにかする方法についての記事です。

yum-updatesd の機嫌を損ねないように dbus を動かす(将来改善される可能性もアリ):

$ sudo yum install dbus
$ sudo service messagebus start

/etc/yum/yum-updatesd.conf を編集して、email, syslog での通知を有効にする:

# how to send notifications (valid: dbus, email, syslog)
emit_via = email, syslog

yum-updatesd の異常時のログがどこにも出力されないので、手動で動作確認する:

$ sudo yum-updatesd --oneshot

2011-06-25

[skype] メールアドレスからスカイプIDを検索されないようにするには

スカイプのアカウント検索機能には、メールアドレスで検索したり、連絡先インポート機能で収集したメールアドレスから一括でIDを検索する親切機能が付いています。

メールアドレスで検索されないようにするには、スカイプのプロフィール編集画面のメールアドレスを削除します。

しかし新しくセットアップされた Skype に初めてログインしたとき (IDがドロップダウンボックスに表示されない状態からログインしたとき) に、登録済みメールアドレスを読み込んでプロフィールに設定してくれる素敵な機能があるので、根本的解決のためには、登録済みメールアドレスを誰も知らないメールアドレスに変更する必要があります

アカウントのメール設定はプロフィールの設定が少々遅れて (一時間程度?) 反映され、アカウントのメール設定の状況に基づいて検索機能は動作しているようです。

パスワードリマインダーはプロフィールのメールアドレスではなく、登録済みメールアドレスで管理されています。また、デフォルト動作は、先の素敵機能により自動的にプロフィールにメールアドレスが登録されるので、メールアドレスで検索可能となっています。

自分がメールアドレスで発見されるかどうかは、[連絡先を追加] から、メールアドレスをメール欄に記入して検索してみると分かります。

参考
Skypeヘルプ – プロフィール情報は誰に対して表示されますか?
> あなたのメールアドレスを知っているお友達は、そのアドレスを使ってユーザを検索し、あなたを見つけることができます。

[skype] 家マークが赤くならないようにするには

コンタクトの近況が更新された時などに、Skypeホームを表すらしい、家マークが時々赤色(オレンジ色?)になって、大した用でもないのに目線を奪って大変迷惑です。この無駄な通知は、以下の手順で回避できます。Skype for Windows 5.3および、5.5.0.110で確認しました。

現在の最新版の 5.5.0.112 では更なる仕様変更で個別に無視するしかなくなりました。以下の手順は古くなっています。

  • Skypeホームの [トップコンタクトを表示] の右にある歯車を押し、スライドスイッチを [通知しない] にする。または、チェックを外し、アップデートを受信しないようにする。
  • さらに、Facebookタブに赤丸が付いて困っている方は、
    「Facebookに接続して、友達からの更新をSkype Homeでチェックし、Skypeから通話を発信できるようにします。」と書かれた初期画面に戻し、そのまま触らないでおくと良い。

    具体的には、[No thanks. I don't want to connect.] を押した場合、
    [歯車アイコン] > [Facebookに接続] > [キャンセル]
    の不可解な手順で、初期画面に遷移する。

    [Facebookに接続]を押した場合、公式ヘルプのこちらの記事を参照:
    SkypeアカウントとFacebookの接続を解除する方法を教えてください。

2011-06-19

[dropbox] 間違って作成したリンクを削除するには

Dropbox の「リンクの取得」という機能を使うと、Public フォルダに入っていないファイル/フォルダでも、個別にファイルをダウンロードできる http://db.tt/***** の形のリンクを作成できます。

うっかり手元が狂ったときなど、作成済みのリンクを削除したい場合は、Dropbox の Web インターフェースにある、リンク - Dropbox から個別に削除できます。

このリンクの取得機能でフォルダのリンクを作成すると、ある短縮URLによってその中が再帰的に公開されたままになるので、大切なファイルの入っているフォルダに共有リンクを与えたままにするのはよろしくありません。

古いバージョンの Web インターフェースではこのリンクのことを共有リンクと表記されており、共有の下の分かりにくいメニューに設定画面が存在していました。

この機能についての公式情報
How do I link to a file or folder?
Simple, fast sharing - Dropbox

[Node.js] 十分な強度のランダム文字列を作る

Math.random() に由来するランダム文字列には十分なエントロピが存在しないので、こんな感じで作ってます。沢山必要な方は fd を開いたままにして再利用すると良いかもしれません。

Base64 できっちりエンコードできるように、最小公倍数(6, 8) = 24 より、24 で割り切れるビット数になるように少し小細工します。

結果を戻り値で欲しいのと、/dev/urandom はローカルにあり、読み取り量も少ないので同期型の API を使用しています。

var fs = require('fs');

function getRandomString() {
    var fd = fs.openSync('/dev/urandom', 'r');
    var str = fs.readSync(fd, 33, 0, 'base64')[0]; // 33bytes = 264bits
    fs.close(fd);

    return str;
}

console.log(getRandomString());
// 実行例: bP/t1gioiyia0s/ECKPT+kpE6TRutrIaeD7vYKdyzNJl

2011-06-15

TOTO TCF581 シリーズの水勢デフォルト値の変更

TOTO のオフィス用ウォシュレット TCF581 シリーズ (TCF581M, TCF581MR, TCF581W, TCF581WR) についての記事です。

これらの機種は公共の場所に設置することを想定していて、立ち去った後、水勢が自動で設定値に戻るようになっています。

多くの場合は中立または最弱に設定されているのですが、ごく稀に変な位置に変更されたままになっていて、不便極まりないです。

この設定は TOTO 公式サイトにある説明書には記載は無かったのですが、以下の手順で変更できます。

  1. [止] を長押し10秒で全ランプ点滅 (メンテナンスモード)
  2. [おしり] でデフォルトの水勢を選択
  3. [止] を押して終了

説明書 には他にも、温水・便座の温度調整、自動パワー脱臭設定の変更の仕方が載っているので、ぜひご参照下さい。

2011-06-09

[google] SSL 検索を使って検索キーワードの秘密を守る

企業内などでプロキシ経由でインターネットに接続している状況で検索エンジンを使った場合、プロキシサーバーのログに検索キーワードが記録されるので、それを回避する方法についての記事です。

そのためには、2010年5月にリリースされた、Googleがプライバシー保護のために用意しているGoogle SSL検索を使えばよいです。

使い方はとても簡単で、通常のアドレスに代わって、以下のアドレスへリクエストするように設定すればよいです。
https://encrypted.google.com/search

Chromeを利用されている方は以下の拡張機能を使うと簡単に検索エンジンを追加できます。
Google SSL Web Search beta (by Google)

2012/11/30 追記
すでに https://www.google.com/ など従来のアドレスをそのまま https に変更するだけでほとんどの Google のサービスにおいて SSL 接続が可能となっております。

2011-05-28

[wimax] WM3500R の Wi-Fi 停止問題についての続報

前回の記事の通り設定していても、週に1回ぐらいの頻度で無線LAN部分がハングアップして、一部の端末だけでなく、何もつながらなくなってしまう問題が発生していて、少し困っていました。

本体のラベルが貼られている底面を下にして机にペタッと置いて使っていると、底面がいつもアツアツなので、ふと思い立って少し浮かせて良く冷えるようにしたところ、すでに2週間ほど安定して動作しています。

デフォルト設定からの変更点:
ファームウエアバージョン: 2.0.0
送信出力: 100%
無線LAN端末(子機)との通信設定: 省電力優先
セカンダリSSID: 停止
症状から想像するにWi-Fiのコントローラのあたりが熱暴走しやすいのかもしれません。管理画面がやたら重くなるのもCPUが熱々だと考えると納得がいきます。有志による分解画像を参照しても、上部(つやつや側)がバッテリで、底部に色々熱くなりそうな部品が載っているようです。

2011-03-13

被災地別 重要Twitterアカウントまとめ

青森県
青森県庁
八戸市
青森県弘前市

秋田県
ABSラジオ

岩手県
岩手県広聴広報課
IBC岩手放送
エフエム岩手
奥州市公式アカウント
岩手日報IWATTE

宮城県
東北放送ラジオ制作班
TBCラジオ畠山 明子
Date fm【デイト・エフエム】
㈱仙台シティエフエム
トラストシティプラザ(仙台)
河北新報ニュース

福島県
Channel rfc【ラジオ福島】
福島中央テレビ スタッフ情報
KFB福島放送
朝日新聞福島総局
FMPOCO 福島県福島市コミュニティラジオ局エフエムポコ
玉川光昭 福島県南相馬市

参考
放送Link集[別冊]_Twitter局アカウント&ハッシュタグList

随時更新中です。

IPサイマル放送(テレビ/ラジオ)まとめ

インターネットでテレビ・ラジオが聞けるサイトのまとめです。

USTREAM(テレビ)
NHK総合 (モバイル用低画質)
NHK総合 (PC用高画質)
TBS
フジテレビ

終了

ニコニコ生放送(テレビ)
特別対応番組につきログイン不要
NHK総合(1ch)
<無線端末向け>NHK総合(​1ch)
フジテレビ(8ch)
<無線端末向け>フジテレビ(​8ch)

終了

radiko.jp(ラジオ)
2011/3/13 17:00よりエリア制限解除で全国より聴取可能でした。
4/11で平常のエリア制限に戻りました。

radiko.jp 復興支援プロジェクト
半年間の期間限定で被災地域のラジオ放送がエリア制限なしで聞けます。

2011-02-12

WM3500R から大量の ARP パケットが来る件について

WiMAXポータブルルーターを自宅回線として常用しているのですが、Wiresharkで無線クライアントを通過するパケットを解析していると、IPアドレス:192.168.0.1、MACアドレス:ルーターLAN側で、やたら大量(100packets/s)のGratuitous ARPが届いていて、何事と思い調査しました。

結局のところ、WM3500Rの無線LAN設定: 高度な設定: 無線LAN端末(子機)との通信方法で、速度優先にすると、無線クライアントがスリープ状態に入らないように(?)嵐のようなARPパケットを送ってくれる親切機能だったようで、省電力優先に変更したら静かになりました。

今どきの無線ルータではこのような実装が普通なのでしょうか。良く知らないので要調査という事にしておきます。

2011/02/17 追記
この設定をしてから、同じ無線ネットワークにつないでいるマシンをスリープした直後に他の無線接続しているマシンのネットがやたら重くなる現象が発生しなくなりました。省電力優先に設定するのをお勧めします。

2011-02-05

[facebook] 映画「ソーシャルネットワーク」を見ました

まとまらないので印象に残った点をメモしときます。全体としては楽しめました。

ショーンが、マークのチームを褒める。インフラエンジニアの不足を発見して、ショーンの友達に頼む。

マークが、成長にサーバーが追いつかないようにならないようにする点を強調する (言及はなかったけどフレンドスターのように失敗しないように)。

Victoria's Secret の子がトイレに行ってるときのショーンの話で、会社を売り急げば損したエピソードを紹介する。そのときの音楽 (下に添付) が格好良かった。

エドゥアルドが交際ステータスの件でもめていた。ウィンクルボス兄弟はボートレースでも SNS でも僅差で負ける。

参考
映画「ソーシャルネットワーク」で使用された楽曲まとめ


Dennis de Laat - Sound Of Violence (Dub Mix)

Google Appsでpostmaster宛てのメールを受信する

Google Apps を使っていて、どこかのサービスで、メールでのドメインの所有者確認のため、管理者しか受信しえない postmaster や abuse 宛てのメールを受信したい場合は、直接アカウントを登録できないので、このヘルプ記事 にあるように、postmaster というグループを作成して、メンバーに配信先を登録すればよいです。

動画オーバーレイ広告の閉じるボタンの罠とCTR

閉じるボタンを押そうとして少し的が外れ、広告を押したことになってしまってムキーってなったりするんですが、よく考えてみると、これは運営側の狙い通りなんじゃないかと思い始めたので、少し調べてみました。

YouTubeとUSTREAMともに、閉じるボタンにカーソルを乗せたとき、カーソル自体は指印のままで変化はありません。×ボタンのレスポンスは、YouTubeは少し良心的で、ごくごくわずかに×印に色の変化がありますが、USTREAMのものは全く変化はなく、カーソルが乗っているのかどうかがとても分かりにくくなっています。

これは、広告を押す人にとって広告を閉じるボタンは関係ないので、通常のクリックスルーレートに加えて、広告を閉じようとしてうっかりクリックしたことになってしまう、うっかりリクリックスルーレートを加える効果があるんではないでしょうか。

うっかりクリックスルーレートを見積もってみると、広告を熱心に閉じようとするマメな人の割合を10%として、うっかりクリック率が10%、とすれば、1%となって、広告を押すのと独立ならCTR 1%追加になるのでぼちぼち儲かりそうです。

[javascript] Unicode空白文字でステガノグラフィ

ふと思いついたので、こちらの記事:ZERO WIDTH SPACE を使って Unicode ステガノグラフィ を参考にして、ブラウザでいじれるようにJavaScriptで適当に作ってみました。


Unicode ZWC Steganography

遊び方
埋め込み済みの文を適量デコーダにコピペしてデコードしてみてください。

解説
埋め込む数字を二進数に変換して、二種類のゼロ幅文字 U+200B, U+FEFFに置換します。それを20文字ごとにしつこく埋め込んで処理済みの文章としています。この埋め込む数字を閲覧者IDにして、サーバーサイドでIPアドレスを紐づけて保存しておけば、コピペ犯人捜し(笑)に使えるのではないでしょうか。

Google Authenticator で簡単に二要素認証を実装する

二要素認証としてワンタイムパスワード生成機を使うには、専用のトークンとか高そうなパッケージが必要そうなイメージ (例: RSA SecurID) がありましたが、iPhone, Android アプリ として公開されている Google Authenticator を使うと簡単に使える感じなので試してみました。

Google Authenticator は OATH で定義されているオープンなワンタイムパスワード生成方法 HOTP (HMAC-based One Time Password)TOTP (Time-based One Time Password) に対応していて、QRコードまたは文字列入力で、Base32 でエンコードされた秘密鍵を登録しておくと、勝手にワンタイムパスワードを作ってくれます。

ワンタイムパスワードの生成方法は、メッセージ認証符号 HMAC SHA1 でカウンター値 (HOTP) または30秒単位の時刻 (TOTP) を処理して、その結果を入力しやすい桁数 (6桁以上) の数値に変換するという感じのようです。

サーバーサイドでは、Perl なら Authen::OATH を使って、同じ秘密鍵を持っていることを、同じワンタイムパスワードの数値が入力されたことでもって認証するという感じでいいと思います。Authen::OATH には Base32 の文字列をそのまま突っ込むのではなく、元のバイナリ値を入力とすることに注意しましょう。

2011-02-04

[android] 電波OFFモードでWi-Fiだけ有効にする

Android 2.2以降では、標準で設定できるようです。機内モードオンの後、Wi-FiオンでOK。機内モード時はBluetoothは使えないようです。

Android 1.6-2.1では、以下の手順で、セルスタンバイで電池を消耗することなく、無線LANだけで通信してくれます。IS01で確認し、確かに電話は圏外になりました。レビューにIS06でも上手く動くとあるので、大抵のAndroid端末で有効なんじゃないかと思います。

  1. Airplane Mode Wi-Fi Toolをインストールして、PreferencesのKeep Wi-Fi Onをオンにする。
  2. 電波OFFモード(機内モード)をオンにする。
    Airplane Mode Wi-Fi Toolからじゃなくても良い。

2011-01-29

[perl] pack, unpack で 16進文字列を扱うメモ

Perl の中でも関数 pack / unpack が Perl 的でとっつきにくい所だと思うので書いてみました。Ruby, PHP にも同様な関数があるようです。

関数名の覚え方は、pack: バイナリ列に pack する。unpack: バイナリ列を unpack する (文字列・数値など元のデータに戻す)。

16進数文字列を扱うときはフォーマットで必ず 'H' の方を使う。

unpack('H*', "\xF1\xE2")  # f1e2
unpack('h*', "\xF1\xE2")  # 1f2e (low nibble first 形式: ほとんどの人に必要なし)

# 繰り返し数の数え方にも注意:バイト単位ではなく[0-9a-f]の文字単位
unpack('H2', "\xF1\xE2")  # f1
unpack('H3', "\xF1\xE2")  # f1e

# 16進数文字列をpackするとバイナリになる
# 'C'は符号無し8bit整数。1バイトで収まるのでエンディアンの区別なし。
unpack('C', pack('H*', '10')) # 16
unpack('C', pack('H*', 'ff')) # 255

数値を扱うときは、符号有り・符号無し・リトルエンディアン・ビッグエンディアンに注意。

公式ドキュメント
pack - perldoc.perl.org - 簡潔にまとまった関数ドキュメント
perlpacktut - 素晴らしく詳細なpack/unpackチュートリアル

日本語訳
pack - perldoc.jp
perlpacktut - perldoc.jp

[jquery] jQuery(html, props)が便利

今更ながらjQuery 1.4からの新機能のプロパティ指定つきDOMエレメント生成は、こんな風に使えて便利です。

$('<p />', {
    id: 'sample123',
    'class': 'sample-class',
    text: '内容はないよう(>_<)',
    css: {
        color: 'black',
        background: '#ccf'
    },
    click: function () {
        alert('clicked');
    }
}).appendTo('body');

解説
特別な意味を持つプロパティ、上記の場合 text, html, css, click以外のid, classはattrとして扱われます。
classは予約語なのでクオートが必要です。

この機能を使わないで書くなら:

$('<p />')
    .attr({
        id: 'sample123',
        'class': 'sample-class'
    })
    .text('内容はないよう(>_<)')
    .css({
        color: 'black',
        background: '#ccf'
    })
    .click(function () {
        alert('clicked');
    })
    .appendTo('body');

詳しくは..
jQuery() - jQuery API

2011-01-28

[Node.js] 文字コード変換を行うライブラリ

なるべくUnicodeの世界で完結させたいと思っていても、歴史的事情によりShift_JIS、EUC-JP、ISO-2022-JPをUTF-8に変換したいなどの状況はまだたまにあると思います。しかし、Node.js本体ではそういう汚いところには関わらないポリシーの様で、encodingとしてUTF-8, UTF-16などしか扱えません。

そこでiconvをNode.jsから使えるようにしたnode-iconvを紹介します。親切なことにリポジトリ内にiconvが同梱されているので簡単にコンパイルでき、これで好きなだけUnicode化を進め、node.jsを布教することができます。

残念なお知らせ:文字コード推測機能は付いていません。

参考
bnoordhuis/node-iconv
nodejs - iconv wrapper?
nodejs - ndoe.js is Shift_JIS Encoding Support?

[blogger] Bloggerで公開した記事の取り下げ手順

Googleのインフラで安定して配信してくれる素晴らしいブログサービス Bloggerで、いったん公開した記事を少しひっこめるには、公開した記事の「投稿を編集」から、「下書きとして保存」を押すと、公開状態から下書き状態に戻り、公開待ちの状態に戻すことができます。

この方法を使うとウェブ上では公開されなくなりますが、Google ReaderなどのRSSリーダーには残るので、それも一掃するには、空の記事で上書きするよう、いったん内容を削除して「投稿を公開」を押し、数分後(BloggerはPubSubHubbub Publisherなので更新が早い)に「下書きとして保存」で非公開にすると良いと思います。

2011-01-25

[wimax] WM3500RのWi-Fiがたまに動作しなくなる件について

価格コム経由でBIGLOBEのWiMAXに申し込んだのですが、このプランに付いてくるWM3500Rの無線LANの動作が若干怪しいことが気になりますが、回避策が分かりました。

2週間ほどのテストの結果、ファームウエアバージョン1.1.0で、自分の見た動作不具合が生じている状況は、

  1. ふと思い立って192.168.0.1の管理画面を開く
  2. 直後からWi-Fiが通じなくなり、SSIDのブロードキャストは継続したまま認証が失敗する
  3. USBでつなぐとDHCP、インターネット接続ともにOK
  4. USBでつないで192.168.0.1を開くと、だいぶ待たされたのち、見慣れない「処理中」のエラーページが開く
  5. 電源の入れなおしで復活

以上のような感じなので、管理画面関連のプログラムが何らかの理由で暴走して、CPUを食い尽くす(?)ような欠陥があるようで、設定変更後再起動した後は、気になっても一切管理画面を開かないようにしていると安定動作しています。

2011/02/02 0:12 追記
先ほど管理画面を開かなくてもこのWi-Fiが死ぬ現象が発生しました。相変わらずUSB経由では問題なくネットにつながり、管理画面では「処理中」が出ます。

2011-01-16

[facebook] 交際ステータスSingleの訳として独身は不適切

映画ソーシャル・ネットワーク作品中でも強調されていた、Facebookの注目すべき機能: 交際ステータスの日本語インターフェースにおける訳語「独身」は、それだけを見ると付き合っている人が居るか居ないかの状態が区別出来ていないので、不適切であると考えます。

映画を見てようやく理解したRelationship Statusの言わんとするところは、日本語圏での「付き合っている人いる?」の質問に対する答えをあらかじめプロフィールに明示する、ということだと思うので、

その訳語で唯一思いあたるのは、
A「付き合っている人いる?」
B「今はフリーだよ」
このBさんの言う「フリー」であって、未婚・既婚・離別・死別の状態を区別するような言葉:「独身」はおかしいと思います。

A「付き合っている人いる?」
B「今は独身だよ」
このような受け答えは今まで存在していないと想像します。

もっと説明的な表現でいくなら、「付き合っている人はいません」「交際中の人はいません」というのはいかがでしょうか。