ISBN10/13 相互変換用コード

使う人がいるかわからんが、図書系のWeb APIを使う場合、必須なので誰かいるかもしれん。ということで置いておく。

いまのところ、ASIN(Amazon管理コード)はISBN10と同義なのでISBN13からASINへの変換はこれで足りるけど、一応Amazon側は将来的な仕様変更の可能性も残しているので、変更になったらここにASIN変換用コードをたさんといかんな。

<?php

function ISBN_9to10($isbn){
  
  // 総和を求める
  for ($digit=0, $i=0; $i<9; $i++){
    $digit += $isbn{$i} * (10 - $i);
  }
  
  // 11から総和を11で割った余りを引く(10の場合はX, 11の場合は0に)
  $digit = (11 - ($digit % 11)) % 11;
  if ($digit == 10){
    $digit = "X";
  }
  
  return $isbn.$digit;
  
}

// 9桁ISBNを13桁新ISBNにする
function ISBN_9to13($isbn){
  
  $isbn = "978" . $isbn;
  
  // 総和を求める
  for ($digit=0, $i=0; $i<12; $i++){
    $digit += $isbn{$i} * ($i % 2 == 0 ? 1 : 3);
  }
  
  // 10から総和を10で割った余りを引く(10の場合は0に)
  $digit = (10 - ($digit % 10)) % 10;
  
  return  $isbn.$digit;
  
}

// 10桁旧ISBNを13桁新ISBNにする
function ISBN_10to13($isbn){
  
  $isbn = substr($isbn, 0, 9); // チェックデジット除去
  return ISBN_9to13($isbn);
  
}

// 13桁新ISBNを10桁旧ISBNにする
function ISBN_13to10($isbn){
  
  $isbn = substr($isbn, 3, 9); // 978+チェックデジット除去
  return ISBN_9to10($isbn);
  
}

// 12桁新ISBNにチェックデジットを足す
function ISBN_12to13($isbn){
  
  $isbn = substr($isbn, 3, 9); // 978接頭辞除去
  return ISBN_9to13($isbn);
  
}

// 12桁新ISBNを10桁旧ISBNにする
function ISBN_12to10($isbn){
  
  $isbn = substr($isbn, 3, 9); // 978接頭辞除去
  return ISBN_9to10($isbn);
  
}

?>

安全な乱数とは何か

PHPでのセキュリティ対策についてのメモについて、第三者に知り得ない文字列の生成(安全な乱数の生成)についてご指摘を受けました(ありがとうございます)。長くなりそうですので、こちらで返信させていただきます。


「第三者が知り得ない文字列(ユーザIDやワンタイムトークンなど)を ハッシュ関数md5関数やsha1関数)を複数回用いて擬似乱数化」< 安全な乱数を理解していない。/ わからないことは「わからない」と書いた方が良い。

これは仰るとおりです。後で引用する水無月ばけらさんも指摘していただいていますが、パスワードが英単語一語などきわめて単純な場合は、ハッシュ関数の組み合わせ(擬似乱数生成アルゴリズム)が相当複雑でない限り、ブルートフォース(総当たり)攻撃で生成語と付き合わせて、生成前の値を突き止められてしまいます(アルゴリズム自体を組み合わせの一つとして考えることもできそう)。

それで、第三者が知り得ない文字列=安全な乱数、を生成するにはどうすればよいか。ばけらさんのご指摘では、安全な疑似乱数を使用して生成する擬似乱数生成器、でしょうか)のが定石だけど、PHP標準では安全な乱数を生成できないのだそうです。

…と、調べた*1限りでは、擬似乱数にも(暗号理論的に)安全なもの[=予想・観測不可能なもの]とそうでないもの[=予想・観測可能なもの]に分けられ、このうち後者の例として、セッションIDの生成に用いられている線形合同法srand関数に用いられているメルセンヌ・ツイスタ法があるようです。

いしなお! - PHPで安全なセッション管理を実現する方法に対する高木さんのコメントへのフォローでは、unix環境で使える /dev/random という乱数デバイスを併用すると良いと書かれています。

この /dev/urandom なるものがどれくらい信用に値するかはもうわからないのですが、Manpage of RANDOM/dev/random - Wikipediaを読む限り、安全でないわけではなさそうです。

ですので、この/dev/urandomのうち、先頭何百バイトかを抜き取り、それを種にしてsrand関数で擬似乱数を生成したものを、mhash関数(SHA-512)を用いてハッシュ値を求めれば大方安全な擬似乱数になるのではないでしょうか。ただ、乱数生成器の取扱い - PHPとPythonを読む限りは、/dev/randomを使わなくとも、だいたい安全な乱数が取れそうです。

<?php $var = bin2hex(mhash(MHASH_SHA512, srand())); ?>

※ もちろん、突き詰めれば予測可能かもしれないですが、そこは「泥棒はもっと不用心な家を狙うんじゃないか理論」を採用しています:)

tumblrのURIの統一 + 日本語化

tumblrの各投稿記事には2種類のURIが存在します(中身は同じ)

APIRSSなどで使われる
http://(tumblrID).tumblr.com/post/(postID)/
tumblrのサイト上で使われる
http://(tumblrID).tumblr.com/post/(postID)/(記事から英数字を抜き出したもの)

API/RSSやテーマからどちらも使えるのであればよいのだけど、残念ながらAPIからは前者、テーマからは後者しか使えないようになっている。

問題は、APIを使ってサイトなんかを作っていると、両者で表示されるURIが違うものだからはてなスターを付けたときそのスターが分散してしまう。

そこでjavascriptでテーマ側のURIを英数字を取り除いてしまいます。ついでに時間表記の日本語化もしてます(要jQuery, tumblrURIは読み替えてください)

デモ:Another side of Liner Note

$(document).ready(function(){
  
  var pattern = /http:\/\/memo\.openvista\.jp\/post\/\d+\/[a-z\-]+/g;
  document.body.innerHTML = document.body.innerHTML.replace(pattern, '\1');
  
  var units_en = {
    0: /seconds? ago/g,
    1: /minutes? ago/g,
    2: /hours? ago/g,
    3: /days? ago/g,
    4: /weeks? ago/g,
    5: /months? ago/g,
    6: /years? ago/g,
    };
  
  var units_ja = {
    0: "秒",
    1: "分",
    2: "時間",
    3: "日",
    4: "週",
    5: "月",
    6: "年"
  }
  
  units_en.__proto__ = Array.prototype;
  units_ja.__proto__ = Array.prototype;
  
  for (var i in units_en){
    for (var i in units_ja){
      document.body.innerHTML = document.body.innerHTML.replace(units_en[i], units_ja[i]+"前");
    }
  }
  
  
});

痴漢冤罪をどう防ぐかという話

映像'08で「痴漢冤罪被害特集」をやっていた。御堂筋線の虚偽告訴事件が有名ですが、今月初めにもこれ関連の判決が出てましたね。東京に行く私としても人ごとじゃないことです。

http://ja.wikipedia.org/wiki/%E7%97%B4%E6%BC%A2%E5%86%A4%E7%BD%AA

性的犯罪は疑わしきは罰せずの原則を適用していくには限界があるので、実際は被害者の証言を信用して有罪になるケースが多い。不起訴あるいは証拠不十分で無罪となったとしても、社会的制裁がオチというのが黒魔法の恐ろしいところ。

そもそも客観的な物証がほとんどないのが構造的な問題でしょう。最近は指紋採取やDNA鑑定などの客観的証拠を重視していく姿勢もあるようだけども、これだと「股間を臀部に押し当てた」と「満員電車で体が擦りあった」の区別がつかないのが問題。

監視カメラの設置を」との意見もあるが、残念ながら監視カメラの映像は物証としては不十分です。というのは、同番組内では車内上部に設置した監視カメラで痴漢のシミュレーション(マネキンね)を撮影してみた様子を紹介していたのですが、被害者の手が映ることなく痴漢が行えてしまったんですね。

おそらく客観的証拠を確保していく、あるいは物理的に男女を隔離するというのが現状を見た上での世論の向かう方向だと思いますが、何か良い策はありますかね。

Google Chrome使ってみた

二三思ったことをメモっておこうかな。

確かにシンプルで必要な機能だけ搭載されているという印象がする。UIはIE7-に似ていて、IE乗換組の学習コストは安く付きそうな感じ。しかし、Picasaのような競合がそれほどいない場所ならともかく、ライトユーザはIEで満足すると思われるので、IE6が今はまだ丁重に扱われている現状では市販PCに標準搭載されない限り注目されるほどのシェアは見込めないでしょう(他のブラウザも同じ話だけど)

それで、ユーザに訴求できる機能面に着目するわけだけど、一番意外だったのはインスタントブックマーク機能にGoogle Bookmarksとの統合がなかったというか全般的にGoogleサービスとの連携がそれほど意識されていないところですね、これはあえて距離を取ってるのかな。当分はシンプルな使い勝手とGears+アプリケーションショートカットによるウェブアプリケーション実行プラットフォームとしての面が打ち出されるのでしょうか。後者が注目されるのはまだまだ先の話になりそう。

個人的にはユーザCSSの機能がないところを見ると、コンテンツ表示管理(=広告ブロック)につながる機能は載せてくる気配がないので乗り換えることはないのだけど、エクステンションAPI搭載後の展開には注目したいですね。

余談の余談だけど、「Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13.」というUA名には失笑してしまいました、お前は何者なのかと。

「スカイ・クロラ The Sky Crawlers」鑑賞記

友達と一緒に見に行ってきました。会場は8割の入りと言ったところで平日にしては入っている方だと思います。以下、ネタバレを含むので未見の方はご注意を。

紋切り型の励ましではなく、静かだけれど確かな真実の希望を伝えたい

人生は辛いもの。でも時々良いことがある。相対的に、生きることは捨てたもんじゃない。

監督の押井氏がサイト上に残したこういうメッセージがどのように表現されているのだろうかと思って、観に行きました。

しかし、夢・焦燥感・希望をどこかに置き忘れたかのように全てを他人事のように振る舞って生きる主人公には(ベタな解釈ですが)ディストピア以外の要素を感じられませんでした。

少なくともそこに生の渇望や希望を見いだす、あるいはそれらを肯定する要素は読み取れることはできませんでしたし、この「空虚な生」のアンチテーゼとしてそれらを描き出せているかと言えば疑問です。むしろ、宿命*1的にキルドレを生きる*2主人公には絶望感すら漂います。

死ぬとわかっていても(であるからこそ)そこに生を見いだしラスボス「ティーチャー」に向かっていくキルドレ達。確かに相対的には生への渇望を求めての行為なのかもしれませんが、私には屈折した生からの逃避にしか思えませんでした。うーん、この映画のどこに希望があったというのだろう。ラストシーンで垣間見えるかすかな希望は若者に向けるにはあまりに弱いのでは(若者はそんなにどん底に絶望しているわけではないと思う)

話とはずれますが「空」のCGは音響も相まって大変迫力がありました。Last Exile以来あんまり良い空中戦を見ていなったのでごちそうさまという感じ。「陸」との良いコントラストになってますね。

まぁ、でも面白いですよ。それは映画そのものじゃなくて、みんなが何を映画に投影しているか観察できる点で。

*1:宿命の定義は鈴木謙介『ウェブ社会の思想』を参照、すなわち「人が自分の人生に関する未来を選択すること、それが宿命のように、前もって決められていた事柄として受け取られる」ということ

*2:より正確に言うならシステマティックなキルドレというシステムを生きる