2012/02/19

Chromeが起動時に三つのランダムなドメインに接続しようとする理由

“Chrome connects to three random domains at startup.” — Mike West

Chromeを起動した際、http://aghepodlln/とかhttp://lkhjasdnpr/のようなランダムなドメインへの接続を試みる。何でこんなコトをしているのかという見当はずれの推測が、いくつか出回っている。事実としては、この挙動は必要なのだ。以下の説明で、この疑問を晴らす。

このような接続要求の目的は、現在使用しているネットワークが、存在しないホスト名への接続要求を検知して勝手にリダイレクトするかどうかを判定するものである。例えば、少なからぬISPが、http://text/のようなDNSルックアップの失敗に対し、http://your.helpful.isp/search?q=text(あなたの親切なISP)へリダイレクトしている。この「親切」な挙動の可否はさておくとして、この挙動はChromeにとって問題を引き起こすのだ。特に、Omniboxで使われている、ユーザーの入力がキーワード検索なのか非標準のドメイン名へのアクセスなのかを判定するヒューリスティックを阻害するのだ。

問題の1つとして、Googleの内部ネットワークはいい例となる。Google内部のgoというショートリンクサービスは、共有しやすい簡潔なリンクを提供している。今、"go"とChromeのOmniboxにタイプしてエンターキーを押した時、それはhttp://go/へのアクセスを意味するのか、あるいは"Go"を検索したいのか曖昧である(ところで、Goは面白いプログラミング言語である)。Chromeはできるだけ「正しいこと™」をするため、検索を実行しつつ、裏で、ひょっとしたらドメインかもしれないこの入力に対してHEADリクエストも発行する。サーバーが応答したならば、グーグルはinfobarを表示して、もしかしてhttp://go/を意図していたのかどうかを尋ねる。そして、ユーザーの回答を、将来のために覚えておくのだ。

お分かりのように、この機能は、ISPがそのようなリクエストを補足している場合、ぶっ壊れてしまう。どんな一単語のキーワードに対しても、infobarが表示されてしまうのだ。だから、Chromeは起動時とIPアドレスの変更時にチェックを行なっているのだ。ところで、Chromeは美しくもオープンソースであるので、この実装を確認してみるとしよう。

まず読むべきなのはIntranetRedirectDetectorだ。Chromeが起動した時、IntranetRedirectorDetectorのオブジェクトを生成する。これは短時間のディレイ(現在、7秒にハードコートされている)を設けて、起動時の重要な処理を妨害しないようにし、その後、IntranetRedirectDetector::FinishSleep()を呼び出して実際の処理をはじめる。このメソッドはランダムなドメイン名を三つ生成して、それぞれのドメイン名に対して非同期HEADリクエストを、キャッシュの生成とcookieの保存を行わないようにした上で、発行する。リクエストが完了したならば、IntranetRedirectDetector::OnURLFetchComplete() が呼ばれ、結果を記録する。もし、三つのリクエストのうち、いずれか二つが同じホストに名前解決された場合、そのホストは、ネットワークの"redirect origin"として記録される。簡単だ。

この情報は、AlternateNavURLFetcherで、Omniboxによる検索に対しinfobarを表示するべきかどうかという判断に使われる。もし、HEADリクエストがChrome起動時に得たredirect originと同じサイトを返した場合、無視される。もし、別物であれば、便利なinfobarの出番だ。

とまあ、こんなところだ。Chromeは起動時に三つのランダムなドメイン名に対するリクエストを発行することによって、Omniboxのヒューリスティックがユーザーの意図に添うようにしている。このリクエストは、ユーザーの個人情報を悪意ある目的でどこかに送信しているわけではないし、トラッキング用でもない。crbug.com/18942を修正するために必要なリクエストであり、他意はない。

以上、Chromeが起動時にランダムなドメインにアクセスを試みる理由の説明。それにしても、そんな馬鹿なことをするISPを糾弾するべきだ。ドメイン名が解決できないならば、解決できないと返すべきなのだ。DNS名前解決をハイジャックすべきではない。

新たな期待できるC++インタプリター、Cling

Cling | ROOT

llvmとそのフロントエンドであるclangを利用したC++インタプリターがROOTから登場した。その名もCling。

ROOTといえば、あのCINTを提供していた有名なROOTである。CINTは、インタプリターにしてはよくやっていた方であるが、いかんせん、古すぎるし、規格準拠度も低い。しかし、Clingではclangを利用している。つまり、高い規格互換性が期待できる。これはすばらしい。

2011年にはすでにアナウンスされていたとのことだが、全然気が付かなかった。

2012/02/18

なぜアメリカは自国の著作権法を世界に押し付けようとしているのか

最近、アメリカが自国の著作権法を世界に押し付けようとやっきになっている。何故だろうかと考えてみたところ、その理由が分かった。このままでは、アメリカの一人負けになってしまうからだ。

疑問は、チャップリンから始まった。チャップリンの後期の作品のいくつかは、まだ日本国内でも保護されているらしい。これには、様々な要素が関わってくる。主な理由としては、旧法と現行法で保護期間の長いほうが優先されるということと、チャップリンの作品はチャップリン個人の著作であるということと、戦時加算らしい。

しかし、チャップリンの多くの作品の著作権は、作品が発表された国、米国内ではすでに消失しているはずではなかったか。ベルヌ条約の相互主義はどうなったのか。短いほうが適用されるはずではないのか。この疑問を解消しようと調べたところ、これが厄介なのである。

アメリカはベルヌ条約の加盟に手こずった国である。何しろ、アメリカの著作権法とベルヌ条約は互換性がない上、法律を大幅に改正する気もなかったからだ。そのために、別の条約、万国著作権条約が作られた。その後、アメリカもベルヌ条約に加盟した。問題は、ベルヌ条約の条文には、アメリカ国内では法による制定がない限りベルヌ条約が適用されないという文面があるのだ。だから、アメリカ国内では、対応する国内法を制定しない限り、ベルヌ条約は効力を持たない。もちろん、これはアメリカ国外には関係がない。両国がベルヌ条約や万国著作権条約に加盟している限り、米国内で発行された著作物は、国外では条約に従う。

しかし、アメリカの条約加盟前に発表された作品では、そもそも条約がなかったのだから、条約の効力は及ばない。つまり、万国著作権条約加入前の1956年4月28日以前のアメリカの作品には、日本で相互主義は適用されないのである。しかし、それ以降には、相互主義が適用される。チャップリンの著作権問題とは、要するにこういう法の合間を利用した問題だったのだろう。しかし、映画がチャップリン個人の作品というのには、未だに疑問だが。

しかし、アメリカ国内では、未だに相互主義を採用していない。

これは、アメリカの昔の作品を保護するには、とても便利なのだが、今の作品を保護するには、どうも不利であるように思う。

今、ある団体もしくは企業が映画以外の著作物を発表したならば、その保護期間は、日本国内では発表後50年である。これは、著作物の発表が日本であろうとアメリカであろうと同じだ。日本国内では50年だ。しかし、アメリカでは公表後95年もしくは創作後120年のうちのどちらか短い方が適用される。

つまり、アメリカが相互主義を採用していないがために、日本国内で発表された著作物の著作権が、50年たって日本国内で消失したとしても、米国内では依然として保護される。にもかかわらず、米国内で発表された著作物は、50年経てば日本国内では消失している。映画でも、日本の70年に対し、アメリカは95年だ(映画の創作に25年以上かかることはあるまい)。これは、日本とアメリカはベルヌ条約と万国著作権条約に署名しているので、ベルヌ条約に変な例外のない日本では相互主義が働くが、アメリカ国内では国内法による定めがないために相互主義が働かないためである。

なるほど、ベルヌ条約の相互主義を勘違いしているアメリカ人とよく出会うのは、このためだったのか。そりゃ、アメリカ国内からみれば、相互主義は自国の長い保護期間を優先するようにみえる。実際は、そもそもアメリカ国内では相互主義が働かないだけなのに。

このまま現状を放置すると、今の著作権が消失し始める頃、アメリカ合衆国とそれ以外のほとんどの国で、非常にアメリカ側に不利な保護期間の差がでてくる。

アメリカがACTAやTPPのような条約を猛烈にプッシュして、アメリカ国内の腐った著作権法を世界に押し付けようとしているのは、こういう理由もあるのかもしれぬ。しかし、これはアメリカの自業自得ではないか。アメリカが本当に行うべきなのは、国内法を改正してベルヌ条約の相互主義を取り入れることだ。そうしなければ、相互主義が相互にならず、外国のみに適用されるので、アメリカにとって不平等条約になってしまうからだ。しかし何故かアメリカは、そういう本来ベルヌ条約加盟の際におこなっておくべきことはいつまでたってもやらず、不平等な国内法を改正せず、自国の著作権法を他国にも押し付けようとしている。

指輪物語の翻訳権ってもしかして切れてる?

J.R.R.TolkienのThe Lord of the Ringsは、1954年から1955年にかけて発表された。一方、日本語の最初の翻訳である指輪物語、1972年に発表されている。

イギリスと平和条約を締結したのは1952年1月3日なので、戦時加算はない。The Hobbitの発表は1937年なので戦時加算があるが、The Lord of the Ringsには戦時加算がない。1970年以前に発表されている著作物なので、いわゆる10年留保で、公開から10年以内に翻訳が出ない場合、翻訳権が消失するはずである。1965年に日本語訳は出ていない。

ということは、指輪物語は、いま日本国内では自由に翻訳していいのだろうか。

The Hobbitの翻訳権がどうなるのかは気になるところである。もともと10年留保で1947年に切れるはずだった翻訳権が約十年+翻訳権の六ヶ月だけ延長されるのだろうか。だとしても、ホビットの冒険は1965年に発表されているので、やはり翻訳権は切れている。

ちなみに、トールキンの没年が1973年なので、いずれにせよ日本国内では、2024年に著作権が切れる。あとたったの12年だ。

雪のおもしろう降りたりし朝

今夜は雪がおもしろう積りたるいとをかし。

京都に来て、始めて、「雪のおもしろう降りたりし朝」という言葉の意味がわかった。京都の雪は美しいのだ。人を煩わすほど積もるのは稀だし、寒さといっても、それほどでもない。ただ、かろうじて地面を白くするのに十分な程度降る。京都では、雪はおもしろい。

2012/02/16

ユーザー定義リテラル補足

前回、ユーザー定義リテラルのすべてを説明したつもりであったが、いくつか細かい漏れがあった。

まず、ユーザー定義リテラルの宣言であるが、実は文法上、空白文字が必要な箇所がある。""と識別子の間だ

int operator "" /*ここに少なくともひとつの空白文字が必要*/ _identifier( unsigned long long int ) ;

空白文字を入れないと、""_identiferがひとつのトークンだとみなされてしまう。

もちろん、この宣言を参照する際にも、空白文字が必要である。

operator "" /*空白文字が必要*/ _identifer( 123ULL ) ;

また、ユーザー定義リテラルのオーバーロードは、あらかじめ定められた仮引数リストやテンプレートしか使えないが、その他は、普通の関数と変わりないということである。もちろん、inlineやconstexprで宣言することもできる。当然、内部リンケージを持つ可能性もある。

inilne unsigned long long int operator "" _inline_udl( unsigned long long int value ) { return value ; }
constexpr unsigned long long int operator "" _constexpr_udl( unsigned long long int value ) { return value ; }

もちろん、アドレスだって取得できる。

unsigned long long int operator "" _udl( unsigned long long int value ) { return value ; }

int main()
{
    using udl_pointer_type = unsigned long long int (*)( unsigned long long int ) ;
    // アドレスの取得
    udl_pointer_type p = &operator "" _udl ;
}

また、当然ながら、名前空間スコープ内に宣言される。名前解決も通常通りである。

namespace foo
{
unsigned long long int operator "" _udl( unsigned long long int value ) { return value ; }
}


int main()
{
    123_udl ; // エラー
    {
        using namespace foo ;
        123_udl ; // OK
    }

    {
        using foo::operator "" _udl ;
        123_udl ; // OK
    }
}

もちろん、オーバーロード解決も通常通りである。

void operator "" _udl( unsigned long long int value ) {  } // #1
void operator "" _udl( long double value ) { } // #2

int main()
{
    operator "" _udl( 123ULL ) ; // #1
    operator "" _udl( 1.23L ) ; // #2
}

また、文字列やテンプレート実引数で受け取る場合のオーバーロードの優先順位は、

  1. 整数リテラルの場合、仮引数unsigned long long int、浮動小数点数リテラルの場合、long double
  2. それが見つからない場合、char const *
  3. それが見つからない場合、テンプレート実引数

となっている。したがって、

void operator "" _u1( unsigned long long int value ) {  } // #1
void operator "" _u1( char const * ) { } // #2

void operator "" _u2( char const * ) {  } // #3
template < char ... Types >
void operator "" _u2( ) { } // #4

int main()
{
    123_u1 ; // #1
    123_u2 ; // #3
}

このようにオーバーロード解決される。

つまり、いくつかの制限と例外的なルールを除けば、およそ関数に適用されるルールは、ユーザー定義リテラルのオーバーロードにも適用される。

ユーザー定義リテラルのすべて

C++11にはユーザー定義リテラルというものがある。私はこの機能が嫌いだ。しかし、どうやらgcc 4.7がある程度の実装を終えたらしい。日本一C++に詳しい男を自称する私としては、試さなくてはならない。そこで、この記事を書く。この記事を読めば、今日から君もユーザー定義リテラルをバリバリに使えるようになる。

まず、C++11では、非常に不思議な理由により、ユーザー定義リテラルは、演算子のオーバーロードという形で実装する。はて、リテラルにつくサフィックスは演算子なのだろうか。それはともかく、ユーザー定義リテラルの識別子には、一言注意が必要である。ユーザー定義リテラルの識別子は、必ずアンダースコアからはじめなければならない。

私が注意深く、「識別子」と書いているのには訳がある。ユーザー定義リテラルの識別子は、「名前」ではないからだ。この詳細を理解する必要はない。重要なことは、必ず「識別子」をアンダースコアからはじめなければならないということだ。ちなみに、通常の「名前」では、アンダースコアから始まる「名前」はグローバル名前空間において予約されているので、使ってはいけないし、アンダースコアに大文字から始まる「名前」はあらゆる箇所で予約語なので使ってはいけない。ふたつの連続しているアンダースコアを含む「名前」も予約語である。「識別子」だからこそ、許される所業である。詳しく説明すると、「名前」は「エンティティ」か「ラベル」を意味する「識別子」でなければならないからだ。これはC++プログラマーにとっては一般常識である。

前置きが長くなった。さっそくユーザー定義リテラルを使ってみよう。

#include <iostream>

// 整数の実引数を二倍にして返すユーザー定義リテラル
unsigned long long int operator "" _twice ( unsigned long long int value )
{
    return value * 2 ;
}

int main()
{
    std::cout << 1234_twice << std::endl ;
}

結果として、2468と出力されるはずだ。まあ、とりあえずこれで、ユーザー定義リテラルというものが何かは分かったはずだ。

ユーザー定義リテラルは、

戻り値の型 operator "" _identifer (仮引数リスト)

という形で宣言する。使う際には、

リテラル _identifer

となる。一応、明示的に呼び出すこともできる。もっとも、明示的に呼び出すぐらいなら、普通の人は普通の関数を使うだろうが。

operator "" _identifer() ;

その他は、通常の関数のように使える。中でどのような処理をしてもいいし、戻り値の型は自由だ。

ユーザー定義リテラルには、大きく分けて四種類ある。ユーザー定義整数リテラル、ユーザー定義浮動小数点数リテラル、ユーザー定義文字列リテラル、ユーザー定義文字リテラルである。

ユーザー定義整数リテラル

ユーザー定義整数リテラルを整数型の値として受け取るには、仮引数の型がunsigned long long intでなければならない。もし、単項マイナス演算子を使ったとしたならば、それはユーザー定義リテラルの戻り値に対して適用される。ユーザー定義リテラルに渡される値は、常にunsigned long long intである。

ユーザー定義浮動小数点数リテラル

ユーザー定義浮動小数点数リテラルを浮動小数点数型の値として受け取るには、仮引数の型がlong doubleでなければならない。

long double operator "" _udl( long double value )
{ 
    return value ;
}

int main()
{
    3.14_udl ;
}

浮動小数点数の場合も、負数は受け取れない。単項マイナス演算子は、ユーザー定義リテラルの評価の結果に適用される。

ユーザー定義整数リテラルとユーザー定義浮動小数点数リテラルをその他の方法で受け取る方法

この整数リテラルと浮動小数点数リテラルのユーザー定義リテラルは、別の方法で受け取ることもできる。文字列と、テンプレート実引数である。

文字列として受け取る場合、char const *を使う。

// 単にstd::string型として返す
std::string operator "" _to_string( char const * s )
{
    return std::string( s ) ; 
}

int main()
{
    // operator "" _to_string("1234")
    std::string s = 1234_to_string ;
    // operator "" _to_string("1.234")
    s = 1.234_to_string ;
}

何のひねりもない単純なコードだが、みれば分かるだろう。整数リテラルを、あたかも""で囲んで通常文字列リテラルにして、そのまま実引数に渡したかのように、ユーザー定義リテラルのオーバーロード関数に渡される。

テンプレート実引数として受け取る場合は、仮引数を取らない。Variadic Templateを使って実装する。

// 単に結合してstd::string型として返す
template < char ... Chars >
std::string operator "" _to_string( )
{
    std::string buf ;
    for ( auto c : std::initializer_list<char>{ Chars... } )
    {
        buf.push_back( c ) ;
    }
    return buf ; 
}

int main()
{
    // operator "" _to_string<'1', '2', '3', '4'>()
    std::string s = 1234_to_string ;
    // operator "" _to_string<'1', '.', '2', '3', '4'>()
    s = 1.234_to_string ;
}

これまた、なんのひねりもない単純なコードだが、みれば分かるだろう。整数リテラルと浮動小数点数リテラルの、各文字がそれぞれ、<'1', '2', '3', '4'>という形で、テンプレート実引数として渡される。

すでに説明したので、いまさら言うまでもないと思うが、この文字列とテンプレート実引数で受け取る機能は、整数リテラルと浮動小数点数リテラル限定である。この次に出てくる文字列リテラルと文字リテラルには使えない。もっとも、聡明な読者には余計なおせっかいであろう。失礼失礼。

ユーザー定義文字列リテラル。

C++11では、5種類の文字列がある。このうち、通常の文字列リテラルとUTF-8文字列リテラルは、型を共有しているので、おなじ仮引数で受け取る。

// 通常の文字列リテラルとUTF-8文字列リテラル
void operator "" _udl( char const * str, std::size_t size ) { }
// ワイド文字列リテラル
void operator "" _udl( wchar_t const * str, std::size_t size ) { }
// char16_t文字列リテラル
void operator "" _udl( char16_t const * str, std::size_t size ) { }
// char32_t文字列リテラル
void operator "" _udl( char32_t const * str, std::size_t size ) { }

int main()
{
    // operator "" _udl("test", 4)
    "test"_udl ;
    // operator "" _udl(u8"test", 4)
    u8"test"_udl ;
    // operator "" _udl(L"test", 4)
    L"test"_udl ;
    // operator "" _udl(u"test", 4)
    u"test"_udl ;
    // operator "" _udl(U"test", 4)
    U"test"_udl ;
}

戻り値の型がvoidという、何の意味もないコードだが、あくまで例示のためである。第二引数は、NULL文字を除く文字数を格納している。第一引数はちゃんとNULL終端されているので安心して欲しい。

また老婆心で忠告するが、char *という仮引数リストは、ユーザー定義文字列リテラルのためにあるのではない。整数リテラルと浮動小数点数リテラルを文字列として受ける場合の仮引数リストである。文字列リテラルには使えない。

とても大事な事なのでもう一度ぐらい忠告しても許されると思うから言っておくが、Variadic Templateは、整数リテラルと浮動小数点数リテラルを受け取る場合の宣言である。文字列リテラルには使えない。

ユーザー定義文字リテラル

文字列リテラルの場合とほとんど変わりない。

// 通常の文字リテラルとUTF-8文字リテラル
void operator "" _udl( char c ) { }
// ワイド文字リテラル
void operator "" _udl( wchar_t c ) { }
// char16_t文字リテラル
void operator "" _udl( char16_t c ) { }
// char32_t文字リテラル
void operator "" _udl( char32_t c ) { }

int main()
{
    // operator "" _udl("a")
    "a"_udl ;
    // operator "" _udl(u8"a")
    u8"a"_udl ;
    // operator "" _udl(L"a")
    L"a"_udl ;
    // operator "" _udl(u"a")
    u"a"_udl ;
    // operator "" _udl(U"a")
    U"a"_udl ;
}

ユーザー定義リテラルとは、これで全てである。ユーザー定義リテラルは、戻り値の型や識別子を除いては、上記のいずれかの宣言でなければならない。これ以外の仮引数リストやテンプレートは使えない。例えば、以下のようなコードはエラーとなる。宣言すらできない。

// エラー、この仮引数リストは不正
void operator "" _udl ( int ) ;

// エラー、通常の関数でなければならない
template < typename T >
void operator "" _udl ( T ) ;

// これもエラー、Variadic Templatesでなければならない。
template < char c1, char c2, char c3, char c4  >
void operator "" _udl () ;

これでユーザー定義リテラルのすべてを解説した。ところで、私はユーザー定義リテラルが嫌いである。

2012/02/15

URLに著作権を主張したマヌケな会社

URLは著作物ではない。もし、コンテンツを保護したければ、アクセスには認証を設けるべきである。鍵のかかっていない家といえども盗みを働くのは違法だ。しかし、公共の場で勝手に音楽をたれ流しておいて、聞いたものを著作権侵害で訴えるのは馬鹿げている。課金ユーザーにのみ音楽を聞かせたいのであれば、最初から公共の場で流すべきではないのだ。

しかし、この通りのマヌケな事件が、すでに自由過ぎる国アメリカで起こっていたようだ。

Can You Copyright a Publicly Accessible URL? | Gear Diary
MobiTV tries (and fails) to censor Internet | Surveillance State - CNET News

MobiTVは携帯向けに動画の課金ストリーミングを提供しているWebサイトである。ところが、このサービスには問題があった。URLさえ知っていれば、誰でも有料コンテンツにアクセスできるという、セキュリティ上マヌケな問題があった。これを受けて、あるフォーラムにそのURLを書き込んだ者がいた。MobiTVはそのフォーラムに対し、DMCAによる取り下げ要求を出した。結果、大いに叩かれた。当たり前だ。MobiTVがすべきなのは、URLへのアクセスに認証をかけることである。秘密のURLは正しいセキュリティではない。単なる偽装である。

さらに悪いことに、そのフォーラムとやらは、HowardForumsだったのである。これは携帯ユーザー御用達のフォーラムである。結果として、MobiTVは大恥をかいた。

URLに著作権を主張した例がないかどうか調べていて発見し、面白かったので書いた次第。

2012/02/14

Gumroadを使ってみた感想

さっそく、Gumroadを使ってみた。例えば以下のようになる。

RFC 2606で規定されている例示用に予約されたセカンドレベルドメイン名情報の購入

上記のリンクから、RFC 2606で規定されている例示用に予約されたセカンドレベルドメイン名の情報を購入することができる。このドメイン名は、IANAが保持しており、ドキュメント内にドメイン名の例が必要になった際に、安心して記述できるので、万人におすすめだ。

と、冗談はさておき、Gumroadは、本当に極限までシンプルにしたサービスであると感じた。機能を絞り、煩わしい設定を出来るだけ省き、誰でも手軽に使えるようにしている。

あとは、悪用をどう防ぐかということだけだろう。まだ試していないが、ファイルのホスト機能もあるようだ。URLはともかく、ファイルは著作物となりうる。Gumroadが本気でサービスを継続する気があるのあらば、他人の著作物を無断で使われることを、何とかして防がなければならない。ハッシュ値チェックなどで、ある程度は自動化出来るだろうが、万能ではない。有人による確認が必要となるだろう。

しかし、動画投稿サイトだって、一昔前は、様々な理由から、非現実的だと思われていたのだ。こんなサービスも、将来当たり前になっているかもしれない。

ともかく、C++の参考書の執筆に戻る。将来、ちょっとしたプログラミングの記事とかがこういうサービスで売り出される時代が来るだろうか。いや、果たして売れるのだろうか。

Gumroadで他人のURLを売るのは違法か?

例示用に予約されたセカンドレベルドメイン名情報の購入

Gumroadを使えば、どんなURLでも売ることができる。すると問題になるのが、自分のコンテンツを他人に販売されるということである。Gumroadが日本の法律に照らしてどうなのかという疑問は、すでに発表されている。しかし、Gumroadを技術的に考えてみると、なにか問題があるとは思えない。

なぜかというと、Gumroadで課金するのは、コンテンツではない。URLである(追記:どうもURLの他に、ファイルをホストするサービスもあるらしい)。URLとは、単にWeb上のコンテンツを指し示す文字列に過ぎない。書籍のISBNと、技術的に異なることはない。URLに著作権を主張できるはずがないので、URLを教えたとしても著作権侵害にはあたらない。

今、私が、近所のコンビニの場所への案内を頼まれて、その案内に対し対価を得たとしても、それは違法ではない。私はコンビニを売った事にはならないし、コンビニで窃盗を働いたわけでもないし、ましてやコンビニの著作権を侵害したわけでもない。私は単に、道案内の対価を得ただけである。

同様に、私がAmazon.co.jpのサイトでの購入の際の操作方法を教えることに対して対価を得たとしても、違法ではない。私はアマゾンを売ったわけではないし、アマゾンの著作権を侵害したわけでもない。私はコンピューターの操作方法の説明の対価を得ただけである。

今、私が、かくかくしかじかに関する書籍はないかと質問されて、その本のISBNを教えることに対価を得たとする。これは違法ではない。私はその本の著作権を侵害したわけではない。私は単に本の存在を教えることに対して対価を得ただけである。ISBNは書名や著作者や出版社などと同じく、単なる情報である。著作物ではない。

とすれば、URLを教えたことに対して対価を得るのは、果たして何か問題になるだろうか。URLにアクセスして、その結果としてコンテンツをダウンロードされたとする。なにか違法なことが起こっただろうか。もし、あるURLに自由にアクセスされたくなければ、そのURLのWebサイトで認証を設けるべきである。それは、URLによって指し示されたWebサイトを提供する者の責任である。

第一、URLを教えて対価を取るようなサイトは、もう五万とあるはずである。リンクを張り、広告を設置していれば、直接ユーザーから対価を取ってはいないとはいえ、対価を得ていることには代わりはない。書名やISBNを教えることに対価をとっても問題にならないように、WebサイトのURLを教えることに対価をとっても違法性はないはずである。

ゆえに、私はGumroadでは、誰でも、どんなURLでも合法的に販売できると思う。誰か反論して欲しい。

唯一何か問題があるとすれば、そのURLが、著作物の違法なダウンロード(著作権侵害)であるとか、日本国政府を打倒して革命を起こすよう主張していたり(内乱罪)、わいせつ物を頒布(わいせつ物頒布等の罪)していたなど、犯罪に関わっている場合、そのURLを教えたことにより、該当の罪の幇助に問われるかもしれない。しかし、幇助というのは、私の知る限り、かなりややこしい概念で、その認定方法もややこしい。そもそも、著作者がそのURLを公開していて、認証なしで著作物をダウンロード出来る場合、それは違法ダウンロードにはならないだろう。違法ダウンロードにならないのだから、著作権侵害幇助にもならないはずだ。

というわけで、私はRFC 2606で規定されている例示用に予約されたセカンドレベルドメイン名の情報を売ることにする。なんと、太っ腹にもたったの100円である。

例示用に予約されたセカンドレベルドメイン名情報の購入

Gumroadの仕組み

今、Gumroadが話題となっている。いったいこれはどういうサービスなのか。どのような仕組みなのか。それを調べたので、メモがわりに書いておく。

Gumroadは、URLの販売代行を行うサービスである。

たとえば、芸術的な絵を描いて、そのデジタルデータを売りたいとする。別に高く売るものではない。例えば、数百円で売りたいとする。広く売るものではない。例えば、せいぜい数十人から数百人程度に売れれば良しとする。デジタルデータに対する課金は、何も目新しいものではない。そのためにはまず、そのデータをダウンロードできるURLを用意する。これは簡単である。何しろ、レンタルサーバーは月数百円から存在するし、無料のファイルホストサービスも存在する。URLを、たとえば、http://www.example.com/art.zipとする。ここまでは簡単である。問題は、このURLを公開してしまっては、金が手に入らない。何とかして、ユーザーに課金させる仕組みを作らなければならない。

ところが、実際にユーザー登録などの機能を提供し、クレジットカード会社と契約してユーザーに課金し、課金済みのユーザーのみに使用が制限されたURLを用意してダウンロードさせる、などという大掛かりなWebサイトを、個人で始めるのは負担が重すぎる。第一、数百円程度のデジタルデータを小規模に売りたい時に、そんな大掛かりなサービスを実装するのは大赤字である。鶏を割くに焉んぞ牛刀を用いんや。

ここに、Gumroadが割り込む。Gumroadで販売したいURL(http://www.example.com/art.zip)を値段とともに設定する。すると、Gumroadはその課金用URLを生成する。そのURLにアクセスすると、課金画面がでる。課金したユーザーには、設定したURL(http://www.example.com/art.zip)が告げられる。Gumroadは手数料を徴収した差し引きを、販売者に渡す。

これがうまくいくかどうかは、興味深いところだ。確かに、購入者の誰かひとりでもURL(http://www.example.com/art.zip)を漏らしてしまえば、この仕組は破綻する。これを防ぐために自前でアクセスに認証を設けるならば、Gumroadを利用する意味がない。しかし、今の時代、デジタルデータを共有するのは、非常に簡単になってる。容量はもはや問題ではない。数十GB、数百GBであっても、違法なアップロードとダウンロードの障害にはならない。破られなかったDRMは存在しない。もしあるとすれば、それはコンテンツに人気がなかっただけだ。とすれば、認証なしのURLが違法に漏れるのと、実際のデジタルデータが違法に共有されるのとは、結局は同じ事だとも言える。(そもそも、インターネット上のURLを公開するのが著作権侵害になるかというと疑問だが)たとえるならば、田舎の畑の前の無人の野菜販売所みたいなものだろう。カネを払わずに野菜を盗むのは簡単である。

だから、なにか安価なデジタルデータを少人数に販売する場合には、Gumroadでも、案外うまくいくのではないだろうかとも思う。あるいは、一昔前に流行った、気に入ったなら金を払う仕組みのいわゆるドネーションウェアなら、まあ損ではないともいえる。

Gumroadの試みは、果たしてうまくいくのだろうか。数年ほど観察すれば分かるはずだ。

2012/02/10

Eolas敗訴! 繰り返す、Eolas敗訴!

Eolas Loses in Web Patents Claim Against Google and Others | PCWorld Business Center

Eolasの持つ二つの特許、特許番号5,838,906(Flashで有名になったHTMLへの外部アプリ起動埋め込み特許)と、7,599,985(インタラクティブなWeb)が、ふたつとも無効になった。

やれやれ、まだアメリカにも一片の良心は残されているらしい。

野郎ども、お宝のハッシュ値のハッシュ値を盗みに行くぜ。でも親分、それって違法?

Avast, Me Hearties: How The Pirate Bay Changed The Way We Steal | TechCrunch
Magnet-hashes for all torrents on The Pirate Bay: 164 MB | Hacker News
The whole Pirate Bay magnet archive (download torrent) - TPB

The Pirate Bayがtorrentファイルのホストをやめて、マグネットリンクをデフォルトにすると発表した時、The Pirate BayをすべてUSBメモリに格納することができるだろうというジョークが出た。そこで、それを実行にうつした人間がいた。PerlでThe Pirate Bayをクロールして、The Pirate Bay上のユニークID、名前、クロール時のピア数、infoセクションのハッシュ値を記録した。その結果、ファイルサイズは164MB、圧縮して90MBとなった。十分USBメモリに収まるサイズである。その記録のハッシュ値のハッシュ値が以下となる。

magnet:?xt=urn:btih:938802790a385c49307f34cca4c30f80b03df59c

なんと、UTF-8ならたったの60バイトだ。紙にすら書ける。先頭の20バイトは余分なので、根本的には、938802790a385c49307f34cca4c30f80b03df59cというたったの40バイトの情報だ。もちろん、これはHEXなので、実際には20バイト分の情報である。

さて、この20バイトの情報は違法だろうか。

前回も書いたように、どこまでを違法とするのかを考えると、とてもメタな考え方をしなければならない。

torrentファイルに記録されているのは、torrentファイル自体を表示するのに使われるべき名前、トラッカーサイト、ファイル名、ファイルの各ピースのハッシュ値などである。技術的に考えて、ハッシュ値にまで著作権が及ぶはずはない。

ところが、世間では、根本的には単なるファイルのハッシュ値であるtorrentファイルが違法であるらしい。実際、The Pirate Bayのファウンダー達は有罪判決を受けている。そこで、The Pirate Bayは、torrentファイルすらやめてしまった。マグネットリンクになった。

マグネットリンクとは、torrentファイル内のinfoセクションのハッシュ値である。つまり、938802790a385c49307f34cca4c30f80b03df59cのようになる。この数字は、The Pirate Bayをクロールして最小限の情報を格納したファイルのtorrentファイルへの識別子とみなすことができる。実際に目的にファイルを得るには、この識別子を元に、他のピアからtorrentファイルを入手、そのtorrentファイルを元に、他のピアから目的のファイルを入手することになる。これは、違法な数字なのだろうか。

著作権はハッシュ値にまで及ぶのか? ハッシュ値のハッシュ値ではどうか? ハッシュ値のハッシュ値を掲載しているWebサイトはどうか。ハッシュ値のハッシュ値を掲載しているWebサイトをクロールしたデータはどうか。ハッシュ値のハッシュ値を掲載しているThe Pirate Bayをクロールしたデータのハッシュ値のハッシュ値、すなわち、938802790a385c49307f34cca4c30f80b03df59cは、果たして違法なのか。著作権侵害幇助だとしても、どこまでが幇助になるのだろうか。

追記:もちろん、このリンクを延々とたどって、最終的にファイルを違法ダウンロードすれば、それは著作権侵害となる事にかわりはない。問題は、ハッシュ値を掲載することが違法になるのか、つまり、The Pirate Bayは違法かどうかということだ。

2012/02/09

Eolasの悪夢、再び

Patent Troll Claims Ownership of Interactive Web – And Might Win | Threat Level | Wired.com

Eolasと聞いただけで身震いする者は、有能な技術者である。わからないものは、未熟者である。Eolasは「HTML内に自動的に外部アプリを起動させてやり取りをさせ埋め込みオブジェクトを表示するための手法」というあまりにも明白過ぎる特許を取って、一時期Webを混乱に陥れた特許ゴロである。わかりやすく言うと、Flashを埋め込むHTMLコード、embedやobject要素がこの特許に抵触する。

Eolasはマイクロソフトを相手取って特許侵害の訴訟を起こした。この訴訟には、WWWの父であるW3Cの長であるTim Berners-Lee本人をはじめ、様々な企業、団体がマイクロソフトを援護したにもかかわらず、結局、特許を覆すことはできなかった。最終的に、マクロソフトは和解をし、非公開の額の賠償金を支払ったということである。一説によると、3040万ドルだそうだ。

もちろん、これはアメリカ国内の話なのだが、ブラウザーを作っている企業の多くはアメリカにいるし、外国企業とて、アメリカという市場を無視することはできないため、この特許を回避する方向に動いた。回避方法とは、Flashの再生には、ユーザーの明示的なマウスクリックを必要とする変更であった。わけが分らない。さらに、Javascriptで動的にFlash埋め込みコードを追加するのも、特許回避であるので、様々なFlash埋め込み用のJavascriptライブラリが流行した。これも技術者の端くれとして本質的に訳がわからない。

そういうわけで、Eolasは特許ゴロの名を(ほしいまま)にしたわけだが、実は、第二弾があった。「インタラクティブなWeb」という特許である。

この特許は、とにかくインタラクティブなWeb全般に関わる。またもや、Tim Berners-Leeご本人をはじめ、主要なWeb企業は裁判で戦っている。

ソフトウェア特許という奇妙極まりないものは廃止すべきである。恐らく特許自体、廃止、ないしは極端に制限すべきだろう。著作権も、もはや時代にあっていない。

2012/02/07

続Appleの罠エディタ

Apple Clarifies iBooks Author Licensing Situation in New Software Update - Mac Rumors

なんでも、あの不思議なEULAの意図は、iBooksというフォーマットにかかる権利らしい。

しかし、日本において純粋なファイルフォーマットが特許性を有するのだろうか。ファイルフォーマットの文法は、プログラミング言語の文法と同じで、特許性も著作権も持たないのではないだろうか。

そういえば、日本でLZWアルゴリズムの特許を取れたのも、これまた未だに理解出来ない。LZWは純粋なアルゴリズムであり、どうやって日本で特許をとれたのだろう。

著作物の定義

たまたま、著作物について面白いニュースが二つ会ったので紹介する。

You Can’t Copyright Porn, Harassed BitTorrent Defendant Insists | TorrentFreak

アメリカ合衆国で、ポルノを違法ダウンロードした者が著作権侵害で訴えられたもので、反論として、そもそもポルノには著作権は認められないと主張している。

これは、合衆国の憲法が、著作権について、

To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries

科学と有用な技術の発展を促進するため、その作者と発明者に期間を限定した排他的な権利を保証する

としているため、そもそもポルノはこの憲法の定義に当てはまらず、故に著作権は主張できない。著作権が主張できないのだから、著作権侵害など存在しない、という論法らしい。

もっとも、なぜか違法ダウンロードをしたとされている日時が、問題の映画の公開一ヶ月前で、そもそもダウンロード不可能であったらしい。

ちなみに日本ではどうかというと、著作権法では、

著作物 思想又は感情を創作的に表現したものであつて、文芸、学術、美術又は音楽の範囲に属するものをいう。

とされている。日本では、憲法で著作権を規定しているような記述がちょっと見つからない。著作権法に著作物が規定されている。

これを考えるに、「思想か勘定を創作的に表現したものではない」か、「文芸、学術、美術、音楽の範囲に属さない」のであれば、それは著作物ではないということになる。

さて、わいせつ物は美術だろうか。四畳半襖の下張事件の上告棄却の判決文によれば、

なお、文書のわいせつ性の判断にあたつては、当該文書の性に関する露骨で詳細な描写叙述の程度とその手法、右描写叙述の文書全体に占める比重、文書に表現された思想等と右描写叙述との関連性、文書の構成や展開、さらには芸術性・思想性等による性的刺激の緩和の程度、これらの観点から該文書を全体としてみたときに、主として、読者の好色的興味にうつたえるものと認められるか否かなどの諸点を検討することが必要であり、

と書いてある。「さらには芸術性・思想性等による性的刺激の緩和の程度」ということは、わいせつ物は芸術性、思想性によって緩和されるものらしい。ということは、わいせつ物自体には芸術性も思想性も認められないのではないだろうか。芸術性も思想性も認められないのであれば、わいせつ物、すなわちポルノは著作物ではないということになる。いや、これは言葉遊びだろう。わいせつ物が、その自身の芸術性、思想性によって緩和されるのだから、わいせつ物にも芸術性、思想性はあるはずである。

ただし、日本でわいせつ物だと認定されれば、それを頒布する行為は、刑法175条によって禁じられている。すると、同様な訴訟が日本であったとしても、わいせつ物に著作権が認められたとしても、わいせつ物であると訴えて、認められれば、相手も刑事罰を食らうのだろうか。わいせつ物であるかどうかというのは、裁判所が判定することである。なにも警察のOBが天下っている団体によって判定されるわけではない。あれはあくまでレーティングであって、わいせつ物ではないというお墨付きを得たわけではないのだ。なにしろ、警察がわいせつ物であるかどうかを判断してしまうのは検閲に当たる。わいせつ物の判断は裁判所によってなされねばならないはずだ。

ちなみに、この訴訟は、アメリカではお決まりの、「お前は著作権侵害をしたはずだ。今すぐ数千ドルを払えば訴えないでおいてやる」という、推定有罪の通告に対し、「そもそも俺はやってねーよ」と主張して反訴したものである。

Oracle sues Google for Java patent, copyright infringement

これは古いニュースだが、興味深かったので考えてみる。OracleはGoogleがJavaの著作権と特許を侵害したとして訴えている。

私の理解する所では、日本では、プログラミング言語を解説した文書や、実装には著作権が与えられるが、プログラミング言語自体には著作権は認められない。同様に、プログラミング言語自体の特許も認められない。日本から見ると、アメリカは不思議な国だ。まあ、Flashを参照するURLを記述するembed要素に特許が認められる国なのだから、なんでもありか。

2012/02/06

親知らずを抜いた後がだいぶ治ってきた

親知らずを抜いた後が、だいぶ治ってきた。一時は頬が腫れ、喉が痛く、熱も出て、最悪だったが、ようやくマシになってきた。今日抜糸予定。

もうすぐ、まともに物を食べられるようになるだろう。おかゆばかりすすり続けていると、なんだか無性にジャンクフードが食べたくなる。

2012/02/05

アゴを印刷する時代

3ders.org - 83 year-old woman got 3D printed mandible | 3D Printing news

従来の方法でインプラントのアゴを作るのは数日かかるが、3Dプリンターを使えば数時間ですむらしい。

2012/02/03

なぜ歴史には海賊が必要なのか

Why History Needs Software Piracy | PCWorld

SOPAとPIPAのような反海賊法を巡っての議論において、我々の関心は、主として現代と近未来に置かれがちである。職と利益に対する被害に対しては、今日、誰が被害をうけるのかということに着目しがちである。

ここでひとつ、ソフトウェア海賊に対して、別の視点からの関心ごとを述べてみようと思う。未認可のソフトウェアの複製が、短期的にみて、いくらかの商業的利益を損ねることに疑いはないが、ここで一歩下がってみると、すこし違った状況が見えてくる。歴史的に考えると、ソフトウェア海賊のもたらす利益は、短期的な損失を大幅に上回っているのだ。もし、技術史を気にかけるのであれば、許諾なくソフトウェアをコピーする連中がいることに、感謝しなければならないのだ。

一件奇妙に聞こえるかもしれないが、海賊が救ったソフトウェアの数は、破壊したソフトウェアの数より多いのだ。すでに、海賊は何万ものプログラムを絶滅から救っており、図らずもデジタル文化の守り手としての地位を証明している。

ソフトウェア海賊は、データをより簡易かつ記録媒体から独立させることによって、データの消失を防いでいる。巨大なシステムの一部として働く全体の知識を持たぬアリのように、デジタル海賊の献身的な行動は、全体として観察すれば、数多くのデジタルコンテンツを保存しているのだ。

海賊による保存効果とは、あまり良く知られてないが、何も目新しいことではない。何世紀にもわたり、石版、巻物、本に至るまで、その最も複製され、頒布されたものが、現代もっともよく保存されているのである。ホメーロス、ベオウルフ、ましてやキリスト教の聖書までも、もし未許諾の複製によらずんば、今日の図書館には残っていなかっただろう。

昔と今の違いは、ソフトウェアの劣化は、世紀という単位ではなく、年単位であり、複製による保存を違法行為にしてしまうのだ。これは深刻な問題である。何千もの文化的に重要なデジタルコンテンツが、今我々がこうして論じている間にも、虚無に消え去ろうとしているのだ。

ソフトウェアの消失

現代におけるソフトウェアの消失の問題は、磁気的媒体に起因する。かつてパーソナルコンピューターで広く使われた記録媒体であったフロッピーディスクは、約束された有限の寿命を持つ。推定寿命は、一年から、保存状態が良くてせいぜい三十年といったところだ。

フロッピーはプラスティックの円盤上の磁気変化によってデータを保持している。時間経過と共に、データを表現する磁気変化は、弱くなり、最終的にフロッピードライブが読み込めないレベルにまで低下する。その時点で、ディスクの中身は、実質的に、消失するのだ。

これは、三十年以上前に、パブリッシャーがソフトウェアをフロッピーディスクで出荷していたことを考慮すると、とても困ったことである。ほとんどの当時のディスクは、もはや読めない状態にあり、その上に記録されていたソフトウェアは、修復不可能なほどに損傷してしまっている。もし、読者が今からバックアップを進めようなどと思っているのならば、悪いニュースがある。時すでに遅からん[訳注:リンク先は、Web Archivesの運営者の一人が、どんなフロッピーでも保存するから送ってくれと頼んでいるサイト、しかし、すでに大半のディスクは手遅れな状態にあることを危惧している]

さらに悪いことに、1980年代のソフトウェアパブリッシャーは、数えきれないほどの人月をかけて、コンテンツの保存を妨害するように努めてきたのだ。海賊行為を妨げるため、彼らは様々な手法で、ソフトウェアをひとつの認可されたディスケット上にロックしようと試みた。ある有名なコピープロテクトの手法は、意図的に壊れたデータブロックをディスク上に配置して、コピー時のエラーチェック機能に引っかからせるようにしている。この手法は実によく働いたので、正規ユーザーの正規購入ソフトウェアの正当なバックアップすら妨げてしまった。

これらのコピープロテクトが、その意図通り、ド素人避けであり、著作権法に従うとすると、これらの手法を用いたディスクで出荷されたソフトウェアは、今や永久に失わてしまっていたであろう。多くの時代を主張する文化財が、メディアコントロールという強欲によって消失してしまったのだ。

危機にひんしているのはフロッピーディスクだけではない。ROMカートリッジによって出荷された何千ものゲームや、アーケード基盤は、今や見つけることすら難しい。しかも、これらは永遠の動作寿命を持たない電子機器上でしか動作しないのだ。パブリッシャーは、いくつかの有名なゲームについては、新しいプラットフォーム上でリリースしている。しかし、大多数のレガシーなゲームは、そのような処置を受けてはいない。海賊はこのようなデータをROMチップから解放し、ソフトウェア上のエミュレーションによって、新しいゲーム機やPC上で、プレイできるようにしているのだ。

また、海賊行為によって、歴史家が海外のゲームを研究するのを容易にしている。いくつかのゲームは、日本限定の書き込み可能なディスクにダウンロードする形で頒布されていたのだ。例えば、ニンテンドーパワーのフラッシュカートシステムやBS-Xサテラビューのような仕組みでだ。これらのゲームは、もし過去に違法にバックアップする試みがなされていなければ、西洋の歴史家からは手に入らなかった代物なのだ。

[訳注:Wiiを持っていないので詳しいことはわからないが、商業的に価値のあるほんの一部のゲームは、WiiのVCで提供されているかもしれない。余りはどうしようもない。これらを合法的に手に入れる方法は、現時点では存在しない。とくにBS-Xは、テレビの電波を利用した配信だったので、正規の方法で購入できるカートリッジがないのだ。もし当時、デジタル文化財の保存の重要性に気がついてバックアップしていなかったとしたら、お手上げである。ちなみにこれらのゲームは、1990年代後半に公開されているので、著作権法が今後も変わらないとしたら、ゲームは映画であるからして、今から約60年後の2070年あたりには、著作権が切れる。しかし、この記事でも言っているように、そもそも保存が難しいのだ。]

ソフトウェアの消失の問題の例として、ゲーム業界をみてみよう。Web上の最大のゲームデータベース、MobyGamesは、現在、約6万件のゲーム情報を載せている。約2万3千ほどのタイトルは、フロッピーディスクやカセットテープを記録装置や、配信媒体として使うコンピューター向けに出荷されていた。

2万3千ものゲーム! もし、ゲームパブリッシャーと著作権法が横たわっていれば、このうちほとんどのゲームは、今後10年以内に、記録媒体の劣化によって、地上から一掃されてしまう。すでに、多くが失われている。

近年、コレクターと保存家は、ビンテージマシン(AppleIIとかコモドール64とかのたぐい)上で動く絶版になったソフトウェアを、ファイル共有サービスや、"abandonware"なウェブサイト上で交換している。この過程で、彼らは地下ソフトウェア図書館を作り上げているのだ。これは、新しいとはいえ、古代の失われたデジタル文明の記録を保存する図書館のようなものだ。

Abandonwareについて

abandonwareとは、すでに販売もサポートもされていないソフトウェアを頒布する大義名分である。これらのソフトウェアは、その著作者から「放棄(abandoned)」されたのだ。それにもかかわらず、ソフトウェアに著作権があり、著作者から、ソフトウェアの頒布許諾を得ていなければ、頒布はまだ違法なのである。

ジャーナリストかつ歴史家として、私はこのような海賊ソフトウェアを使って、仕事をしている[訳注:著者のBenj Edwardsは、コンピューター史とゲーム史専門の歴史家を自称している]。私だってこんなことはしたくないのだが、合法的な方法が存在しないのだ(詳しくは後述)。

この未来の歴史家にとって必要な資料である地下図書館による収集は、我々のデジタル遺産を保護するための、人類の反骨精神あふれる勇敢な行動である。この後に述べるように、ソフトウェア史における脅威は、過去にあるのではない。目前にあるのである。

何故ソフトウェアを保護するのか

さらにこの問題に詳しく踏み込む前に、そもそも、何故我々はソフトウェアを保護しなければならないのかという理由について考えよう。ソフトウェアは、そのあまりに短い寿命から、それほど重要視されていない。ソフトウェアとは電子による動的な表現を、コンピュータースクリーン上に投影したものであり、それ自体はさほどの意味をもたない。我々は、物理的な物体に価値を見出すのである。

しかし、ソフトウェアは強力な道具であり、我々の文明にとっても重要な意味を持つ。博物館を眺めると、道具の存在によって、ある社会がどのような状態にあったのかを知ることができる。もし、例えば、ある文明に脱穀機があったならば、我々はその文明が、100年前に比べて、麦の収穫をより速く行えたと知ることができる。これは、転じて、人口の爆発的増加を説明できるだろう。

同様にして、我々は人類の状態を、ソフトウェアツールを調べることで推定できるのだ。未来の歴史家は、今日の我々はいかにして音楽における音程調整を実現していたかとか、いかにしてCGIアニメーション映画を制作していたのであろうか、などという疑問を持つかもしれない。知識と、様々なバージョンのAuto-TuneやPixar RenderManやAdobe Photoshopの体験なくしては、彼ら歴史家が、そのような疑問を解き明かすことは難しいであろう。

ソフトウェアは娯楽でもある。文化である。本や、音楽や、映画と同じく、芸術がソフトウェアによって表現されている。多くはゲームだ。これらは各世代の文化を反映している。

マリオが誰であるかを知らない15-35才のアメリカ人がいるであろうか?(もしそんな奴を見つけ出してきたとしたら、そいつは1980年から1999年にかけて、地下室に監禁されていたに違いない)

法律に抵抗する保存家達の活動に感謝するべきである。これによって未来の歴史家はマリオが文化に与えた影響をより深く考察することができる。「なぜ古代人はみな、ドット絵のキノコ人間がプリントされたTシャツを着用していたのであろうか」とか、「どのゲームにマリオが登場したのか、それはなぜか」などという疑問も、明らかにすることができるであろう。

任天堂がこの先200年生き延びることは、可能である。しかし、彼らはこのような疑問に全て正しく答えることはできないであろう。企業は顧客に見せられる商業的価値のあるものしか残さないものだ(例えば、スーパーマリオブラザーズ3を繰り返しみせる)。歴史家は、すべてを見せる。ホテルマリオ[訳注:CD-iで公式な許諾を得て発売されたお世辞にも出来がいいとは言えないマリオのゲーム、アメリカ限定]、マリオルーレット[訳注:コナミから発売されたアーケードゲーム、いわゆるメダルゲー、日本限定]、アイアムアティーチャー スーパーマリオのセーター[訳注:ディスクシステムにてこのタイトルで発売されたマリオをつかった編み物の教育ソフト、日本限定]。これらのゲームは、海賊によらなければ、200年を生き延びることはできない。なぜならば、任天堂はこのような低品質のゲームを、やや恥じており、著作権法で封印して、朽ちるに任せているからだ。

我々には失うものが多すぎる

ソフトウェアの消失が過去の話であってくれればいいのだが、現代のソフトウェア市場においても、まだこの問題は存在する。App Storeやその他のデジタル配信システムは、よくヘンテコで制限されたライセンス契約をさせたがる。時には、デバイスすら制限することもある。我々がソフトウエアを所有することすら認めていないのだ。

横暴なDRMと統一された配信方法のおかげで、ほとんどのデジタル配信されているソフトウェアは、これらの配信ストアが廃止された場合、歴史的資料から消失する。これは事実である。彼らはいずれの日か、サービスを廃止する。もしこの事実に恐怖を覚えないとしたならば、歴史の授業が必要だ。

50万種類もの本が、急にその機能を終え、魔法のように世界中のすべての複製物が機能しなくなったとしたらどうであろうか。ポン。その中にあった情報は、消えてしまうのだ。紀元前48年のアレクサンドリア大図書館の焼亡に匹敵する文化的ダメージである。あの炎によって、それまでの西洋文化の歴史は、灰燼に帰したのだ。

さて、iTunes App Storeをみてみよう。デジタル文化の象徴である50万ものアプリを保持している。これは、たったひとつの企業によって支配されている。そして、将来廃止されるときには(もしくは、古いアプリをサポートしなくなった時には、Appleはすでに昔のiPodでやらかしている)、これらのアプリに対する合法的なアクセス方法も消え去るのだ。iDeviceに縛られた、購入したアプリは、このシステムが機能をやめた時、寿命を迎える。すでに、古いアプリは消え去っているのだ。なぜならば、開発者がアプリをストアに保持しておくための年会費100ドルを払わないがために。

歴史的にみれば、我々はハッカーと海賊たちが、iTunes App StoreやPlayStation StoreやWii Shop ChannelやXBox Live Arcadeやその他のオンラインのダウンロードサービスから入手できるあらゆるアプリを、秘密裏に保存してくれていることを願うしかないのだ。

クラウドソフトウェアはどうだ? もし、我々のソフトウェアツールが中央管理され、インターネットを介して実行されるようになれば、海賊行為は困難になる。これは、保存されないということを意味する。歴史にとって、最悪である。

もし、古人類学者が、1万3千年前のやじりでバイソンを仕留めることができるかどうか疑問に思ったならば、単に槍の先にくくりつけて投げてみればよい。もし、やじりがその開発期間中、クラウドによって自動的にアップデートされていたならば、我々は最新設計のものしか知りえないことになる。やじりは現存していないであろう。我々は、古代のアメリカ原住民が、どうやって劣化ウラン弾でゲームをプレイしていたのかなどと疑問に思うことであろう。

考えてみたまえ。一年前のGmailのインターフェースってどんなだった?ストリートビューが搭載される前のGoogle Mapってどんなだった? クラウドベースのソフトウェアツールの昔のバージョンにアクセスできない未来の歴史家は、スクリーンショットや個人の証言記録により、昔のツールがどのくらいの性能を持っていたのかを推し量るしかないであろう。もし、まだ存在していればの話だが。

クラウドではないソフトウェアならば、未来の歴史家は古いバージョンを試すことも可能だ。歴史家はやじりと同じようにツールを使い、当時の人間と同じ活動を再現できるのだ。たとえば、歴史家はAtari 800エミュレーター上でAtariWriter を実行して、1980年代のドキュメント作成を再現でき、これによって当時のフォーマットの必然性を実感できるであろう。

完全なるクラウド依存のゲーム(たとえばOnLive)は、脅威である。OnLiveにゲームソフトフェアの保存を期待するなどというのは、近所の映画館が、フィルムの歴史を保存していてくれるだろうを期待するようなものである。彼らは単に、その時点で商業的に価値のあるものしか上演しない。残りは破棄してしまうのだ。クラウドゲームも同じである。

新たな大図書館は、すでに焚書され始めている。我々はすでに、その煙を嗅いでいるのだ。

企業が歴史を支配すると、改変する

今日のデジタルApp Storeで使われているDRMは、将来の正しい歴史認識に対する重大な脅威である。そりゃ、ソフトウェアを作った企業は、製品に対する権利を、今は持っている。しかし、ひとたびコンテンツが消費され、大衆文化に取り入れられたならば、それは世代のものである。それは単なる商業製品以上の役割をはたすのだ。そして、コンテンツは文化財として、保護、保存されるべきである。

いつ変更され、消え去るとも分からないものを保護、保存するのは難しい。もし、VHSテープがApp Storeのように機能していたのならば、ジョージ・ルーカスは我々が購入したスター・ウォーズ映画を強制的に特別版にアップデートできるのだ(もちろん、ルーカスOSとの互換性を保つためである)。その過程で、昔のバージョンは上書きされてしまう。誰か知らん、将来、ルーカスは自分の映画が来に食わなくなり、Willowに書き換えてしまうかもしれない。法的な権利が彼にあったとしても、文化に対する窃盗である。

[訳注:日本において、Steamではすでに似たようなことが起きている。何故か正規購入したはずの日本語版が、後で英語版に差し替えられることがままある。そして、日本語版は購入不可能になる。]

iOSのアップデートの頻度に筆者は参っている。アップデートに伴い、過去のバージョンを消してしまうのだ。保存作業も面倒だ。確かに便利で強力な機能には違いないのだけれど、ダウンロードするたびに、歴史が書き換えられてしまうのだ。もし、1990年代からPhotoshopがこのようにアップデートされていたならばどうなっただろうか。レイヤーをサポートした最初のバージョンを持っている人はいるだろうか。そのような歴史的に重要なソフトウェアが消失してしまうのだ。同様に、もし我々が、すべてのPCアプリケーションに対し、完全にコントロールされた唯一の供給方式による自動アップデートを受け入れたならば―もうすぐそこに控えているよ、Windows 8のことさ―我々は、将来のデジタル遺産を破壊してしまうのだ。

制限的なDRMを受け入れた時、我々はソフトウェアとメディアのパブリッシャーに、デジタル文化の歴史を、意のままに削除、コントロール、捏造する力を与えているのだ。だからこそ、DRMは人類にとって根本的に悪であると感じるのだ。DRMは人類の正当たる文化遺産を破壊してしまうのだ。

もちろん、ソフトウェア作者は、今行われているように、ある一定の期間において、独占的な権利を与えられ、それによって対価を得るべきである。しかし、だからといって、歴史的な保存に対する妨害を許してはいけない。

アレキサンドリアで二千年前に起こった出来事を繰り返してはならない。大図書館の焚書を生き延びた巻物は、著作者の許諾なしに、複製され頒布されたものだけなのだ。残念なことに、当時の図書館職員は複製を防ぐために入館を厳しく制限していたので、焚書を生き延びた書物は非常に少ない。もし、我々がソフトウェアの保存に対する法的根拠を作らなければ、今から数千年先の文明には、海賊によって違法に複製されて頒布されたコピー品しか残らないであろう。

ソフトウェアの文化に与えた影響は、他の著作物に匹敵する。今こそ、書籍や映画と同等に、図書館で電磁的芸術品を合法的に保存するべきなのだ。そのような図書館を設置するのは、しかし、非常に難しいのだ。

デジタル図書館の困難性

もし、我々の文化の歴史を今日までたどって検証したければ、図書館に行くであろう。図書館には、無料で利用できる広範なアナログデータが収集されている。ソフトウェアを同じ方法で検証しようとしても、不可能だ。実用的で広範なソフトウェア図書館というものは、現在、合衆国では違法だからだ。

誤解しないで欲しい。ソフトウェア図書館を作るのは可能である。しかし、その実装は、現実的に役立たずなのだ。法律の範囲内で、実現可能な図書館というのは、公式に複製された物理的なソフトウェアの記録媒体を、物理的な書架に格納することである。つまり、記録媒体の劣化と時代遅れの問題がついてまわる。書架に陳列されているものが動く保証なんてどこにもない。

ソフトウェア図書館のより現実的な方法は、固定された記録媒体からデータを解放し、冗長化されたハードディスク群に収めることである。司書はハードディスクをアップグレードすることによって、劣化による消失を防ぐことができる。ソフトウェアは、ネットワーク間で自由に転送でき、エミューレーター(ソフトウェアのオリジナルなプラットフォームをシミュレートしている)上で実行されることにより、歴史的な検証に利用できる。

残念ながら、この実用的な方法は使えない。何故ならば、現在のところ、合衆国アメリカの著作権法においては、著作者の許諾を得ずして、ソフトウェアをコピー―オリジナルの記録媒体からの解放のために必要な作業―して、公衆で共有するのが、違法だからだ。(法律は合法的なバックアップを認めているが、他人と共有することはできない)。さらに、デジタルミレニアム著作権法においては、コピープロテクション技術を迂回して、そのような複製を作成することすら違法なのだ。

現在、フロッピーディスクを、まるで書籍と同じように、書架に収めている図書館が存在する。これらの団体は、本と同じように、十分に注意を払って保護すれば、コンピューターディスク上のデータは永久に保持されるなどという間違った思い込みをしているのだ。しかし、彼らにデータの消失を防ぐ方法は何もない。データは新しい記録媒体に複製されねばならないのだ。将来いずれ、法律が無視されるか―あるいは改正されるだろう。

著作権の時代遅れの前提条件

現在の合衆国アメリカの著作権法は、良い意図を持っているものの、デジタル財産の保存に対する大いなる脅威がある。なぜならば、電子的記録媒体の劣化速度と、フォーマットが時代遅れになる速さを考慮に入れていないからだ。

著作権法を制定した政治家は、19世紀風の法的な前提条件をもとにしている。著作物は、パブリックドメインになって自由に複製できるようになるまでまで、記録媒体に安全に固定されるという思い込みだ。例えば、紙の本だ。紙の本は保存条件次第で、数千年もの間、データを保存できる。

デジタルデータの場合、多くのプログラムは保護期間終了(合衆国アメリカでは著作者の死後70年)の数十年も前に、地上から消え去ってしまう。記録媒体の劣化と、フォーマットが時代遅れになることにより、どの図書館が合法的にバックアップするよりも速く、消え去ってしまう。

解決法のひとつとしては、ソフトウェアの著作権の保護期間を、妥当な期間に制限することだ。たとえば、最大で20年とか。そうすれば、保存家は、古いソフトウェアが忘却の異次元に消え去ってしまう前に保存できる確率が飛躍的に上昇する。

また、司書がソフトウェアを保存する目的でコピープロテクトを解除するのを完全に合法にする必要がある。現在のDMCAにおける一時的なDRM解除を可能にする条件は、あまりにも厳しすぎて、十分ではない。

別の解決法としては、新たな法を制定して、著作権保護を受けたいパブリッシャーは、DRMフリーなバージョンのソフトウェアを、合衆国アメリカの国立図書館の記録媒体に依存しないアーカイブに納めなければならないとする。ソフトウェアは後に、研究者のために提供される。必要であれば、このようなデジタル図書館のコンテンツは、商業的活動を保護するために、一定の猶予期間をおいた後に公開される。たとえば、5年とか。

ソフトウェアの消失を看過してはならない

我々の文明は、商業により支配されており、利益を受けている。そのため、商業に従事するものを保護したいと思う。その中で、とある連中が、目的を達成するため、海賊を厳しい法規制によって撲滅したいと考えている。しかし、海賊とデジタル配布とは切っても切り離せないものであり、自由を放棄しない限り、完全にコントロールすることはできない。そのような法規制は、海賊活動を地下に潜らせるだけで、むしろ海賊にかかわらない、正当な技術の発展を妨げる。その技術こそが、今日のソフトウェアの存在を成立させたというのに。

ソフトウェアの劣化を司る4つの力

ソフトウェアを消失に追いやる主な力が4つある。

力その1:物理的劣化

いかなるデジタル記録媒体も、データを永久に保持できない。すべてのコンピューターのデータの記録媒体は、時間経過に伴い、次第に劣化していく。その過程で、データは失われる。

力その2:記録媒体の時代遅れ

技術が進歩するにつれ、あらゆるストレージのフォーマットは、時代遅れになり、ついに、全く使われなくなる。これにより、将来データを取得するのが困難になる。

力その3:コピー防止

商業的理由により、ソフトウェアパブリッシャーは歴史的に、ユーザーがパブリッシャーの許諾なくソフトウェアを複製できないように細工してきた。このような手法は、ソフトウェアの正当な保存を妨げる。

力その4:商業的価値の消失

すべてのソフトウェアには、ある期間の商業的寿命がある。技術革新の圧倒的な速度によるものだ。これにより、ソフトウェアはある短い期間にしか、商業的に複製、頒布されない。

現在のところ、我々は、十分に頑張れば、いかなる娯楽品、あるいはソフトウェアプログラムであっても、無料で手に入れられる。いまだに何百万人もの人々が正規のソフトウェアや映画や音楽などの複製物を取得するために現金を払っているにもかかわらずだ。これにより、業界は大きく、より高売上になっている。

まだ人々がデジタル媒体を購入するという事実は、海賊というのはそれほど問題ではないということだ。実際、海賊というのは別の問題への解決方法なのだ。過剰に保護された知的財産という問題だ。あの無茶苦茶なDRMを使い、より過剰な反海賊法規制を支援する企業が、歴史的価値を保存するためには、多少の商業的利益の減少も致し方ないという見解をもってくれればいいんだが、それはフリーマケットですら目的ではないのだから、期待はできない。

今、この文化の歴史を保存するのは、この我々の世代にかかっている。我々は著作権法を改正し、海賊行為によらずに、ソフトウェアを歴史的資料として保存できるように働きかけねばならない。

ソフトウェアを愛するのであれば、買って、使って、作者を対価を与えるべきである。私はちゃんとやっている。私は製品によって金銭を得る権利を支持している。しかし、文化的権利の為に立ち上がることを恐れるな。もし無茶なDRMやコピープロテクトが、歴史の保存の脅威であると感じたならば、戦え。コピーしろ。安全な場所で確保しろ。そしていずれ共有して、消失しないようにしろ。

現代では、いくらかの連中から犯罪者だとみなされるかもしれないが、彼らは歴史の悪の方のいる連中だ。今から500年後に、古代のプログラムをロードして実際に検証するときに、当時から生存していてお前を著作権侵害者だなどとそしる者などいやしない。

一年前のGmailのインターフェースを覚えているかというところで、ハッとした。Gmailは毎日使っているのに、実際、覚えていない。もし、電子メールの歴史について書こうとしたならば、Gmailについて述べない訳にはいかない。Gmail以前にもクラウドベース(個人的に、クラウドという言葉はバズワード臭くて好きではないが。)のメールサービスはあった。しかし、Gmailが画期的な容量とインターフェースを提供したからこそ、爆発的に流行ったのだ。

MegaUploadで、まさに焚書がおきようとしている。FBIはキム・ドットコムと他の社員を逮捕し、会社の資産を差し押さえた。まだ裁判は始まってすらいない。キム・ドットコムが実際に犯罪者であるかどうかは、まだ裁かれていない。たとえ違法であったとしても、その利用者は、全員が違法な目的でサービスを使っていたわけではない。なにしろ、オンラインストレージである。しかし、MegaUploadの口座を凍結されているために、MegaUploadはサーバーの維持費が払えず、MegaUploadを合法的に利用していた人達のファイルが、いま消失しようとしている。アレキサンドリア図書館の焼失、秦の始皇帝の焚書坑儒は、いまだに行われているのだ。

もちろん、クラウドにデータを預ける危険性というのは、オンラインストレージやGmailだけではなく、このブログにも言えるわけだが。

2012/02/02

だいぶ良くなってきた

いまだにおかゆしか食べられないが、親知らずを抜いた後は、だいぶよくなってきた。とりあえず熱も下がり、頬の腫れもだいぶひいてきた。今は、むしろ糸に痛みを感じる。早く抜糸してもらいたいところだが、残念ながら来週まで待たなければならないとか。前回も、最終的には糸の存在が気になるようになった。

2012/02/01

噛みごたえのあるものが食べたい。

親知らずを抜いた後はまだ痛む。昨日は頬が腫れてふくれあがり、熱が出て頭がぼーっとし、悲惨な目にあった。今日は、熱はないし、腫れも治まってきているようだ。しかし、アゴを動かすと傷が痛む。唯一食べられるのは、水を米の10倍いれて作った、液体のようなおかゆだ。野菜も相当細かく刻まないと食べられない。ああ、何か噛みごたえのあるものが食べたい。

2012/01/30

親知らず再び

またもや親知らずのあたりの歯肉の盛り上がりが気になってきた。今日の午後、抜く手はずになってる。ああ、またひもじい思いをするのか。

前回の時は、四日間ほどゼリーしか食べられなかった。水をのむのも辛かった。おかゆや豆腐すら受け付けないとは予想外だった。

さて、レントゲンによると、私は親知らずが一本欠けているそうだ。一本はすでに抜いた。二本目も今日抜く。三本目はどうなるのだろう。今のところ、それほど問題にはなっていないが。

2012/01/25

車をダウンロードする時代

The Pirate Bay - The galaxy's most resilient bittorrent site
Pirate Bay To Offer Physical Item Downloads - Slashdot

The Pirate Bayが3Dプリンターのモデルデータ用のカテゴリーを作ったそうだ。アナウンスがぶっ飛んでいて面白い。

進化:新しいカテゴリー

我々はここThe Pirate Bayで、常に未来を見据えている。一つ確かなこととして、将来、我々の社会は、より共有をするようになるだろう。デジタル通信は共有を容易にし、これからもさらに簡単にしていくことに疑いはない。そしてインターネットの進化により、データはアナログからデジタルになった。更にここで次の一歩を進めるべきだろう。

今日、多くのデータは最初からデジタルで作られている。もはや、アナログからデジタルへの変換ではないのだ。もはや変換時の劣化を気にする必要もないのだ。なぜなら、デジタルでは一対一の完全なコピーが可能だからだ。音楽、映画、書籍等など、すべてがデジタル媒体になっている。しかし、我々は物理的な存在であり、依然として物理的な物に触れる必要がある。

思うに、コピーにおける次の進化は、デジタル媒体から物理的媒体となるだろう。これは、物理的な物体である。我々はこれを名付けて、Physiblesと呼ぶことにした。データは物質に変換可能なのだ。思うに、三次元プリンターやスキャナーは、その第一歩である。思うに、近い将来、車の交換部品を印刷できるようになっているだろう。20年もすれば、靴をダウンロードできるようになっているだろう。

この変化が社会にもたらす利益は多大である。もはや,物理的な物品を全世界に流通させる必要はなくなる。不良品の返品などといったこともなくなる。児童労働も撲滅できる。空腹ならば食物をプリントすればよい。もはや、レシピどころか料理そのものを共有できるようになるのだ。その気になれば、フロッピーを本当にコピーすることさえ可能だ。

思うに、共有の未来は、物理化可能なデータであろう。この辺で、ちょっと名前を、The Product Bayとでも変えてみるべきかもしれない。残念ながら、今、新しいロゴを作るアーティストがいない。しかし未来では、それすらダウンロードできるはずだ。(訳注:ロゴのダウンロードなのか、人間のダウンロードなのか・・・)

さっそく、海賊船の形状データへのリンクが登録されている。

3Dプリンターは非常に興味深い技術である。もちろん、今の3Dプリンターは、基本的にはインクジェットで、特殊な樹脂としてのインクを堆積させてプリントしているにすぎない。車を印刷するには、印刷後に金属と比較できるような特性を持ったインクが必要になる。靴を印刷したければ、ゴムのように変化するインクが必要になる。食べ物を印刷したければ、食べられるインクが必要になる。味や匂いを印刷したければ、もちろんそれもインクにしておかなければならない。そしてもちろん、3Dプリンターは相当の精度が要求される。

3Dプリンターはすでに現実化されているし、すでに大人のおもちゃを印刷できるほどの精度がある。木靴や下駄のようなものなら印刷できるだろう。しかし、このようなぶっ飛んだ構想を実現できる3Dプリンターが、はたして我々が生きているうちに現れるのだろうか。

MPAAの警告で、「車を盗んだりはしないだろう?」というのがあるが(そして、著作権侵害と窃盗の混同ということで叩かれているが)、果たして、車をダウンロードする時代は訪れるのだろうか。

2012/01/22

日本人が知るべき記事

Inside the Gaijin Dungeon at Narita Airport in Japan
Gulag for gaijin

事実だろうか。いかにも有りそうな話ではあるが。

追記、エコノミストに載ったので海外で色々と議論されているが、どうもこの話、100%真実かどうか怪しい。理由もなしに入国拒否を受けたと言っているが、VISAに関する情報を、弁護士と相談の上で、とか、プライバシー上の理由で(自分のWebサイトで名前も家族の名前も犬の犬種までも公開しているのに今更何のプライバシーがあるのか)とか、報道機関と独自契約を結んだからなどという理由で説明を拒んでいる。ひょっとしたら、観光客用のVISAで仕事をしていたのではないかとも言われている。

コダックモーメント

What Happened To Kodak’s Moment? | TechCrunch

コダックの131年の栄華、デジタルカメラへの取り組みの遅さ、過去の栄光を捨てきれないプライド、富士フィルムとの戦い。結局何もなくなってしまったので、過去の膨大な特許を利用して、特許ゴロに成り下がった。そして、破産回避の再建手続きに至る。コダックの歴史と経緯をかなり掘り下げて、しかも簡潔にまとめてある。

一方、富士フィルムはどうなったかというと、コダックよりだいぶマシだ。今や、液晶ディスプレイに必要なフィルムのシェアの大部分を占めているそうである。また、化粧品や健康食品にも手を出している。個人的にはあまり好きではないが、儲かることは確かだ。古典的なカメラやフィルム事業は、規模を落として細々と続けているそうだ。まあ、会社の起源というプライドから続けているのだろう。社運をかけるほどではないから、経営に影響が出るほどの赤字にもならないということだろう。

ただ、どうもこれを読んでいると、既視感を覚える。いま、日本企業は技術の分野で振るわない。デジタルカメラでコダックを打ち破ったソニーなど、今はもう落ち目だ。思うに、時代がハードウェアからソフトウェアに移行しつつあるのに、いまだにハード屋の気概が抜けてないのではないだろうか。このまま、昔のアメリカ企業と同じ轍を踏むのだろうか。

2012/01/21

2011-01 pre-Kona 2012 mailingの簡易レビュー

2011-01 pre-Kona 2012 mailingが公開された。

最新のドラフト規格はN3337になる。今回は、単なる文面の細かい修正に留まる。したがって、これを最新のC++11の規格を学ぶために参照しても、恐らく差し支えないであろう。しかし、以前にもC++標準化委員会のMLで、規格書の値段の高さを冗談めかしたコメントにて、「今後公開される無料のドラフト規格は修正を含んでいるので、現行の400ドルもする正式な規格書よりベターといえるのではないか?」という疑問も沸く。閑話休題(あだしごとはさておき)

N3322: A Preliminary Proposal for a Static if
N3329: Proposal: static if declaration

N3322とN3329の根本的な違いがわからない。なぜほとんど同じ提案のペーパーが二つ公開されたのだろうか。

コンパイル時条件分岐の提案。暫定的なキーワードとして、static_ifを使うとすると、以下のようにかける。

static_if( 条件 )
{

}
else
{

}

ifと何が違うのか。それは、条件分岐がコンパイル時に行われることである。たとえば、

template < typename T >
void f( T && t )
{
    static_if( std::is_same<T, std::vector<int>>::value )
    {
        t.push_back( 0 ) ;
    }
}

このようなコードが可能になる。従来のifでは、もし、テンプレートパラメーターTの型が、push_back(int)というメンバー関数を持っていなければ、コンパイルエラーになる。しかし、static_ifはコンパイル時に行われるので、コンパイルエラーにはならない。

これは、現在でも、テンプレートやオーバーロード解決を駆使することによって実現できる。実際、大昔のC++98においても、STLを正しく実装するためにはコンパイル時条件分岐のテクニックは必須である。であれば、最初から言語によるサポートをしたほうがよいのは当然だ。ちなみに、D言語ではネイティブでサポートされているとの由。どこからかD言語信者の勝ち誇ったかような雄叫びが聞こえてくるが、空耳であろう。

N3323: A Proposal to Tweak Certain C++ Contextual Conversions, v3

以下のコードを考える。

template< class T >
class Holder
{
public:
    Holder( ) = default ;
    Holder( T val ) : val( val ) { }
    operator T & ( ) { return val; }
    operator T ( ) const { return val; }
private:
    T val ;
} ;

まあ、よくある簡単なクラスだ。テンプレート引数の型を保持して、ユーザー定義変換で、あたかもその型のように振る舞うクラスだ。変換関数が非const版とconst版に分かれているが、これによって、オブジェクトがconstでも使えるようになる。さっそく使ってみよう。

    Holder<int *> p ;
    p = new int(0) ; // OK
    *p += 1 ; // OK
    int * pointer = p ; // OK

実に楽だ。では、使い終わったので保持しているポインターをdeleteしよう。

    delete p ; // エラー

残念ながら、これはエラーになる。なぜならば、ここではポインターへの暗黙の型変換が行われる。その際、「ポインターに暗黙に変換できる唯一の方法」を要求しているからだ。ところが、ポインターに変換する方法は二つある。よって、エラーとなる。

ではどうするか。明示的なキャストを使う方法もある。しかし、プログラマーというのは怠惰な人間なので、常に一文字でもタイプ数を減らす方法を模索するものだ。

    delete (p+0) ; // OK
    delete +p ; // OK

delete pが通らないのがバカバカしくなるコードだ。これを解決するために、TとTのリファレンス型を返す変換関数がある場合を認めようという提案。

N3324: Terminology: "indirection" versus "dereference"

規格の文面で、「ポインターを経由した間接アクセス」という意味の用語が統一されていない。そのため、すべてのdereferenceを、"indirecting through a pointer"という表現に置き換える提案。単純な置換えだが、かなり広範に渡る変更となる。

N3325: HTML for C++ Standards Documents

C++標準化委員会の公開するペーパーは、色盲やポータビリティを考慮して、HTMLにしようという提案。

ただし、主要ブラウザーがHTML5(というより、HTML5という名前自体に意味がないが)に進みつつあるなか、厳格なHTML 4.01に固執するのはどうかと思う。また、文字コードにはASCIIを使えというのも今時ありえない。第一、委員の多くが、ASCIIでは表現できない名前を持っている。したがって、作者は文字コードがASCIIだと信じていても、実はISO-8859-Xを使っていたりする。

そもそも、HTMLファイル内に、<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">などと書くのは、どのブラウザーからも機能しないと見放された太古の笑うべき仕様である。誰も正しい文字コードを指定しなかったから、信頼できないのだ。自己言及的なことに、同じく発表された、N3336が、HTMLファイル内ではWindows-1252であると主張しておきながら、"您好世界"という文字列を使っている。HTMLファイルの文字コードは、実際にはUTF-8である。こんなジョークでは何にでも笑う大阪人すら笑わせられない。

N3326: Sequential access to data members and base sub-objects

全世界の変態の皆様、特にBoost.Fusionユーザーの皆様、大変長らくおまたせ致しました。長年待ち望んでいたであろう機能の提案でございます。

unionではない任意のクラスのすべてのデータメンバーの型の一覧を、std::tupleでアクセスできる機能の提案。これさえあれば、メタプログラムがますます面白くなるだろう。

N3327: A Standard Programmatic Interface for Asynchronous Operations

非同期処理のためのライブラリの提案。

N3328: Resumable Functions

名前通り、レジュームできる関数の提案。これにより、非同期処理が実にシンプルに書ける。非同期処理のために単純なlambdaを複数書くのがめんどくさい人向け。

N3333: Hashing User-Defined Types in C++1y

C++11では、ハッシュテーブルを用いたコンテナーを追加した。unordered_setとunordered_mapである。そして、ユーザー定義型からハッシュを得るためのインターフェースも提供した。しかし、ユーザーがハッシュを実装するための補助は何もない。自分の用意したクラスをコンテナに入れたいユーザーは、自分でハッシュの算出を実装しなければならない。しかし、十分に強いハッシュ関数を実装するのは、一般人には困難である。現状を放置すれば、弱いハッシュ実装を使ったプログラムが世にあふれるであろう。そのため、ハッシュ関数の実装を助けるインターフェースを提供する提案。

この提案で用意されるのは、ひとつのプロセスがその回の実行に限り、ローカルにハッシュテーブルを構築するのに必要な強度のハッシュである。このハッシュ値は、プログラムの実行ごとに異なるものが出力される。つまり、ハッシュ値をディスクに格納して、次回の実行時に読み込んで使うということはできないし、複数のプログラムでハッシュ値を共有することもできない。また、文字列のハッシュ値を比較して、内容が一致しているかどうかを確実に確かめられるほどの強度もない。ましてや、セキュリティ上の目的でこのハッシュ値を使うことはできない。ハッシュ関数は目的毎に実装が異なり、すべての利用例をカバーしたハッシュ関数の実装が不可能なことはもちろん、ハッシュ関数のインターフェースの統一もいいアイディアではない。この提案されているハッシュ関数はあくまで、STLのコンテナに使うのに十分な強度のハッシュである。

N3334: Proposing array_ref<T> and string_ref

配列や文字列へのリファレンスというのは、現実によく使われる型である。しかし、どの型を使うかというと、定まった型がない。たとえば、std::vectorを使うことができる。しかし、何もstd::vectorにこだわる必要はない。たとえば、ポインターとその長さでもいい。文字列にしたって、std::stringのこともあれば、ポインターと長さのこともある。

もちろん、テンプレートを使って汎用的に実装することはできる。しかし、実装が複雑になり重複も生まれる。そのため、array_refというクラスを作り、どんな型でも、ある一定の操作方法さえ提供していれば、それを配列とみなして処理し、ユーザー側には統一されたインターフェースを提供しようというのが、このペーパーの提案だ。そのため、ユーザーコードは、わざわざこのような古典的な内容のために、クラスや関数自体をテンプレート化しなくてもよくなる。

N3335: Filesystem TR2 Proposal

TR2で採用する予定のFilesystemライブラリーの叩き台。Boost.Filesystem V3がベースになっている。

N3336: Adapting Standard Library Strings and I/O to a Unicode World

名前の通り、既存の文字列や入出力のライブラリーを、C++11で採用したUnicodeに対応させようという提案。TR2に採用予定。我々Unicodeに生きる日本人としては当然の変更である。

N3339: A Preliminary Proposal for a Deep-Copying Smart Pointer

unique_ptrとsmart_ptrをディープコピーできるようにする提案。ディープコピーとは、ポインターが指し示す派生関係にあるクラスの実行時のオブジェクトのコピーである。俗にクローンとも呼ばれている。

struct A { } ;
struct B : A { } ;
struct C : B {  } ;

A * get() ; // 実行時に型をnewして返す。

std::shared_ptr< A > p1( get() ) ;
std::shared_ptr< A > p2( /*ここで、p1の実行時の型のオブジェクトをnewコピー構築して渡したい*/ ) ;

p1は、実行時にA, B, Cのいずれかの型を取る。実行時に、この型のオブジェクトを何とかしてディープコピーしたい。

これらのスマートポインターは、いわゆるpimplのような実装を隠す手法に使われる。その際、ディープコピーができると嬉しい。そこで、ディープコピーを補助するためのインターフェースの叩き台を提案している。

N3340: Rich Pointers

コンパイラーの支援により強力なRTTIを提供するrich_ptrの提案。大規模な動的サーバーや分散システム、動的プログラミング言語の実装などに使われることを想定している。

N3341: Transactional Language Constructs for C++

2008年から始まった、C++にトランザクショナルメモリーを導入するワーキンググループの経過発表。

N3342: Digit Separators coming back

ユーザー定義リテラル「貴様のようなニューグラマーのなり損ないは、Rejectされる運命なのだ。わかるか!」
数値区切り「まだだ! まだ終わらんよ!」

C++11には入らなかった、区切り付き数字の提案。大きな数字、たとえば123456789が、アンダースコア区切りで、123_45_6_789と書けるようになる。何桁で区切っても構わない。正直、クソなユーザー定義リテラルよりこっちがC++11に入って欲しかった。提案された文法では、既存のクソなユーザー定義リテラルの文法とは曖昧にならない。

int x = 123_4_5_6_780 ; // 123456789

N3344: Toward a Standard C++ 'Date' Class

日付を表現する標準Dateクラスの提案。標準ライブラリーとして広く使えるライブラリーを作るのは難しい。

N3346: Defect Report: Terminology for Container Element Requirements - Rev 1

規格の文面の、コンテナー要素における、用語を統一する修正。

N3347: Modules in C++ (Revision 6)

近代的なプログラミング言語なら普通は備えているモジュールの提案。いつか#includeはもとより、プリプロセッサーのサポートを終了できる日を夢見て。もちろんC++だから、プリプロセッサーと共用できるように設計されている。

N3348: Scoping of operator new

現在、グローバル名前空間スコープとクラススコープでしか認められていないoperator newのオーバーロードを、名前空間スコープで宣言できるようにする提案。

N3349: Ease of using namespaces

本気で提案しているのかちょっと理解しかねる提案。namespace内の名前を無視させるディレクティブ"ignore namespace"の提案。以下のように使う。

namespace foo { class X { } ; }
namespace bar { class X { } ; }

using namespace foo ;
using namespace bar ;

void f()
{
    ignore namespace foo ;
    X x ; // bar::X 
}

このように、ignore namespaceディレクティブがある場所では、指定された名前空間内の名前をすべて無視する。こんなのが何の役に立つのか。おそらく、有名なライブラリのヘッダーをincludeする際に使うのだろう。

// C++11のインライン名前空間
inline namespace Win32 {
#include <Windows.h>
}


int GetLastError() ; // たまたまWin32 APIと名前が一致する関数

void f()
{

{// このスコープではWin32 APIは使わない。
    ignore namespace Win32 ;
    int result = GetLastError() ; // Win32 APIは無視される。
}

}

ある名前空間に属する名前をすべて無視するディレクティブなんて泥臭い機能である。それこそ、using namespaceよりひどい機能である。しかし、現実のプログラミングでは、どうしても変更できない巨大なライブラリ(しかも名前空間を使っていない)を複数組み合わせることを余儀なくされる。ライブラリが巨大であれば、どうしても名前の重複は避けられない。その際、わざわざスコープ解決演算子を使うのはめんどくさい。結局、これなしではもっと泥臭いコードになるのを回避する泥臭い機能なのだろう。それにしても・・・やはり泥臭い。

N3350: A minimal std::range<Iter>

そのまんま、Boost.Rangeの同等ライブラリのTR2への提案。

N3351: A Concept Design for the STL

C++11では却下されたSTLのためのコンセプト。一時C++11のドラフトに入っていたものより洗練されているとのこと。特に、たったの41のコンセプトしか定義せず、コンセプトマップを必要としない実装で、しかもテンプレートメタプログラミング臭いトリックが使われていないそうだ。

N3352: C++ Binary Fixed-Point Arithmetic

固定精度の整数と実数のライブラリの提案。これ上限が示されていないのだけれど、例えばcardinal<1024>にすれば、0 <= n <= 2^1024の範囲の整数クラスが使えるんだろうか。

N3353: C++ Concurrent Queues

同期キューライブラリの提案。

N3353: C++ Concurrent Queues

ストリーム(iostreamのストリーム)のためのロック機構の提案。しかし、ストリームなんてまともに使われていないから今更無駄だと思うのだが。

N3355: C++ Distributed Counters

マルチスレッドな環境で使えるカウンターの提案。頻繁にインクリメントされるが、読み出しは稀であるカウンターを想定している。複数のスレッドからのインクリメントは高速に行える。そのかわり、読み出しの遅さは許容する。

N3356: C++ Mutable Threads

スレッドプールより低レベルなライブラリーの提案。通常のスレッドは、あるひとつの関数を実行して、その関数から戻った際に、実行を停止する。しかし、ひとつの関数を実行するためだけにスレッドを作るのは非効率的な場合がある。例えば、小さな関数を大量に非同期に実行させたい場合などだ。そのような場合に使える、再利用可能なスレッドライブラリーである。このライブラリーは、スレッドプールの実装に使える。スレッドプールというには、やや低級なライブラリである。

以上。さて、今年こそC++本を完成させないといけないのだが、流石に疲れてきた。思うに、紙書籍という媒体には、もう未来がないと思う。それに、どうやら私はひとつのまとまった本を書く才能がないらしい。ブログなら簡単にかけるが、本は難しい。今の私を古人に擬すならば、橘成季だろう。

古今著聞集の作者である橘成季は理想主義者だった。彼は当時の公家らしく、様々な芸事に手を出した。競馬、詩文、作文、音楽、舞踊、はては絵までやっている。しかし、今日の我々は、橘成季を知らない。彼の作品はそれほど評価されず、残っていないからだ。彼は当時はやりだった説話集も作った。理想主義者らしく、説話を分類し、話の典拠を明記し、当時の公家日記に見つからないものはその旨も記した。しかし、古今著聞集は、一流にはなれなかった。読んでいても文章はつまらないし、量でいえば今昔物語に負けている。理想は高かったが、惜しいかな、本人の力量がどうしようもなく足りていなかったのだ。

思うに、もう少し軽いノリの本を作るべきだったと思う。ブログのような、あるひとつの主題に対して短い文章を書いたものをまとめた、それこそ説話集のような形式を取るべきだったのだと思う。代わりに今書いているのは、規格書の劣化コピーだ。それなら最初から規格書を読めばいいのだ。もし英語が読めないとしたら、その者は今日においてプログラマーとなる資格はない。

ともかく、始めたことは終わらせなければならない。初心者向けではない本でしかも自分ですら未熟だと思う内容なのだから、どうも売れる気がしない。しかも悲惨なことに、この数年、本の執筆だけを、如何にしてプログラミング言語の文法と機能を教えるかということだけを考えてきたので、まともにプログラミングできなくなっている。プログラマーとしては役立たずだ。これが終わったら、この業界からは身を引くべきなのかもしれない。C++を極めた挙句プログラマーにはなれませんでした、とは笑い草だ。いや、実際には、極めてすらいないのだ。

2012/01/19

今日起きた企業による権力の悪用

An abuse of power given the freedoms these companies enjoy in the marketplace today - Boing Boing

またもやCory Doctorowによる記事。

Xeniが火曜日に書いたように、MPAAはSOPAとPIPAに反対するブラックアウト運動がお気に召さないらしい。アメリカ映画協会の議長かつCEOである名誉会長のChris Doddは声明で、「今日起きた企業による権力の悪用」と称した。

お前が言うな。

あのスキップ不可なFBI警告(ひどく忌み嫌われていて、しかもDVDは他人に貸し出すことができないなどという法的に間違っている警告)をすべての商用DVDに付加させた団体のCEOはお前じゃないか。すべての映画にあの侮辱的な映画の違法ダウンロード警告をつけさせた団体のCEOはお前じゃないか。

しかも、お前がCEOをしている団体が、DMCAで、あの忌々しい警告や広告をスキップする機能をもったDVDプレイヤーの製造を違法にしたんだろ。

お前だって、「今日起きた企業による権力の悪用」の味は知っているはずだ。

そういえば、最近の映画やゲームには、スキップ不可な警告文やロゴやらが多すぎる気がする。海外ゲームのトレイラーに必ず付いているあのレーティング警告もうざい。

2012/01/17

ハドソンを祭る文

歳は辛辰に在り一月某夜、大恐慌の冬の赤字駅に停まりし時、一星忽焉として墜ちて声あり、嗚呼ハドソン死す矣、而して其光栄ある歴史は全く抹殺されぬ。

嗚呼汝ハドソンの事、吾人之を言うに忍びんや、想うに二十余年前、アタリのクソゲーいまだ余波を米市場に及ぼし、ゲーム興隆の宏謨は正に大頓挫を来すの時に方って、祖宗在天の霊は赫として汝ハドソンを大地に下して、其爆弾男の声を揚げ其十六連打を放たしめたりき、而して汝の父母は実に爆弾と陸蒸気を愛する神ゲーの正気なりき、実に世界を振蘯せるゲーム進歩の大潮流なりき。

是を以て汝ハドソンがゲーム興隆の為めに戦い、ゲーム進歩の為め闘うや、策略をもって爆弾で囲み貧乏神をなすりつけ、残機無きも屈せずコンティニュー無きも撓まず、凛乎たる意気精神、真に十六連打の慨ありき、而して今安くに在る哉。

汝ハドソンの起るや、世間の偏見は益々甚しく迫害は愈よ急也、ゲーム時間は制限せられたり、所有は禁止せられたり、請願は防止せられたり、而して捕縛、而して放逐、而して牢獄、而して電源遮断、而も汝の残機の減るを見るが如し、幾万のお小遣いを蘯尽して悔いざる也、幾百のセーブデータを損傷して悔いざる也、豈是れ汝が一片の理想信仰の牢として譲らざる信念のありしが為にあらずや、而して今安くに在る哉。

汝ハドソンは如此にして堂々たるゲーム会社になれり、幾多ゲーマー、暇人の五臓を絞れる熱涙と鮮血とは、実に汝ハドソンの糧食なりき、殿堂なりき、歴史なりき、嗚呼彼れ高橋や、毛利や、橋本や、桜田や、川田や、其熱涙鮮血を濺げる名人は、汝ハドソンの前途光栄洋々たるを想望して、従容笑を含んで宣伝に就けり、当時誰か思わん彼等忘却せられて即ちハドソンの死せんとは、彼等の熱涙鮮血が他日其仇敵たるヌルゲーとソーシャルゲーと劣化続編の唯一の装飾に供せられんとは、嗚呼彼熱涙鮮血や高難易度や今安くに在る哉。

汝ハドソンや、初めや聖賢の骨、英雄の胆、目は日月の如く、舌は霹靂の如く、攻めて取らざるなく、売りて売れざるなく、以て一たび陸蒸気ゲームの新天地を開拓し、リアルファイトを誘発するの偉業を建てたり、而も汝は発展の才に非ざりき、其死亡はスペランカーのジャンプより脆くして、直ちに旧態依然の怠惰の為めに征服せられたり、而して汝が光栄ある歴史、名誉なる事業今安くに在る哉。

更に想う、吾人年少にして友人の家にてファミコンを遊べるとき、無慚破戒の爆弾男は友人と吾人の貴重な時間を奪いたり。当時諸君の神ゲーのセンスは忘れざりき、而して見よ今や諸君は劣化続編のコナミ、パチンコ企業の忠実なる子会社となり、しかも消失に甘んじたり、而して吾人独り一枚のキーボード、多数のコピペ改変のみして、尚お神ゲーの復興の為めに奮闘・・・せざりき、汝ハドソンの死を吊し霊を祭るに方って、吾人豈に追昔撫今の情なきを得んや、かつての神ゲーのTAS動画を眺めて、慨然として賦して曰く、「ヌルゲー死ね、家ゲー死ね。一本道ストーリー重視クソ食らえ。昔ながらの硬派な2DのRPGと2Dのプラットフォームとスポーツ系FPSをよこしやがれこんちくしょう。バニーホッピングもストレイフもロケットジャンプもできないなんてふざけんな」。嗚呼大衆迎合の世は澆季なるかな、而も光栄ある汝の歴史は今や全く抹殺せられぬ、吾人唯だ此愚痴をつぶやきて以て汝を吊するあるのみ、汝ハドソン若し霊あらば髣髴として来り饗けよ。

2012/01/15

The Pirate Bayは違法か?

ここ数日、SOPAがらみの記事の翻訳をしたので、そのついでに、著作権問題の原因の一端を担っているともいえる、The Pirate Bayの最近の興味深い動きについて調べたことを書いてみようと思う。具体的には、The Pirate Bayが最近発表した、torrentファイルのホストをやめるという宣言だ。ただし、これはThe Pirate Bayの終了を意味するのではない。もっと間接的になるだけなのだ。最終的には、このブログ記事が違法かどうかという問題になるだろう。

The Pirate Bayとは、現在最大手の、マグネットリンクとtorrentファイルをホストしているサイトである。しかし、もうすぐ、torrentファイルをホストしなくなるであろう。マグネットリンクだけを載せるサイトになるはずだ。

まず前提の定義。

  • 著作権者の許可を得ずに複製、公衆送信などをされるファイルを「違法ファイル」とする
  • 違法ファイルのアップロード、ダウンロードを違法とする
  • プロトコルとその実装は違法ではないとする

この記事では、「違法ファイル」とは、複製、公衆送信すると著作権侵害となるファイルを意味する。

違法ファイルのアップロードやダウンロードが違法かどうかということに関しては、様々な議論がある。特に国内では、何をダウンロードするのかあらかじめ分からないのに、ダウンロード違法化とはどういうことだという議論もあるが、その懸念は、この場合、問題にならないから、とりあえず一律違法とする。

プロトコルとその実装は違法ではないということは言うまでもないことである。何故ならば、現在、最も著作権侵害に使われているプロトコルはHTTPであり、その実装はブラウザーだからだ。本記事で扱うBitTorrentプロトコルなど目ではない。HTTPプロトコルとその実装を違法化しようという試みは、無論、言うまでもなくカオスに失敗するであろう。

さて、The Pirate Bayというサイトは何をしているのか。その歴史を紐解けば、最初は、公開トラッカーサーバーであった。The Pirate BayのWebサイトは、The Pirate Bayという公開トラッカーサーバー上のtorrentファイルを検索、ダウンロードできるサイトであった。どんなファイルでも受け付けるので、当然、違法ファイルで溢れかえることになった。

技術的には、トラッカーサーバーは、ファイルのアップロード、ダウンロードは一切行なっていない。トラッカーサーバーが行うのは、ファイルのアップロード/ダウンロードをするノードの管理である。これは違法だろうか。ノードは違法行為を行うかもしれないが、ノードの管理は、果たしてどうであろうか。著作権侵害幇助だろうか。

さて、ノードの管理が違法かどうかはともかく、これは問題視され、実際に警察による捜査まで行われた。そこでThe Pirate Bayは、トラッカーサーバーの運営をやめてしまった。The Pirate Bayは、torrentファイルのホストと検索を提供するだけのサイトになったのだ。

技術的には、torrentファイルは、ダウンロード/アップロードするファイル自体のデータは含まない。ファイル名や、ハッシュ値などの情報を含む。BitTorrentプロトコルも発展し、今や、トラッカーサーバーを必要としなくなっている。ファイル名やハッシュ値に著作権保護などされるわけがないので、torrentファイル自体は違法ではない。私がこのブログに、あるファイルの名前とハッシュ値を書きこんでも、違法ではないはずである。さて、これは違法だろうか? まだ幇助しているといえるのだろうか。

さて、最近のことだが、The Pirate Bayはマグネットリンクをデフォルトにすると発表した。また、将来的には、マグネットリンク一本でいくとも言っている。

技術的には、マグネットリンクは、ファイル名やハッシュ値すら含まない。ただ、torrentファイルのinfoセクションの抜粋である。実際、マグネットリンクとはBitTorrentとは関係ない、以前からあるただのURIの規格である。このURI schemeは、ローカルなアプリに任意の引数を渡して起動するURIである。たとえばこんなふうに記述される。

magnet:?xt=urn:btih:8ac3731ad4b039c05393b5404afa6e7397810b41&dn=ubuntu-11.10-desktop-i386.iso&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80

このリンクは、Ubuntu 11.10のインストールディスクのISOイメージへのtorrentファイルへのリンクである。The Pirate Bayがubuntu-11.10-desktop-i386.iso (download torrent) - TPBで提供しているマグネットリンクは、たったのこれだけの単純な文字列だ。マグネットリンクに対応したBitTorrentクライアントをインストールした上で、マグネットリンクに対応したブラウザーを使えば、上記リンクをクリックすることで、BitTorrentクライアントが起動する。そして、マグネットリンクを経由して渡されたinfoセクションをもとに、torrentファイルを自動的にダウンロードする。その後、取得したtorrentファイルを使い、ファイル本体のダウンロードも自動的に始まる。

このように、The Pirate Bayの歴史は、私から見ると、迂回の歴史に見える。まずノード管理をやめ、今はtorrentファイルすらなくそうとしている。すると、ここで一つ疑問が持ち上がる。違法ファイルのホストは違法である。これはいい。しかし、違法ファイルにリンクしているThe Pirate Bayが違法であるとすると、The Pirate Bayにリンクしているこのブログ記事はどうなるのだ。違法なのだろうか。いや、リンクを貼るまでもない。今や、正確なURIなど示さなくても、"Pirate Bay"と記述すれば、Googleなどを使って、検索されてしまう。これは違法なのだろうか。

しかし、あるサイトにリンクはおろか、名前すら言及してはいけないとしたら、一体どうすればいいのか。某巨大匿名掲示板の例にならって、某巨大torrentファイルのinfoセクション検索サイトとでも書くべきだろうか。しかしそれは第二の名前をつけるだけだ。

ちなみに、日本のWinny裁判は、Winnyを開発したことが罪に問われたわけではなく、Winnyを開発したことが著作権侵害の幇助罪にあたるかどうかが争点になった。最高裁の判決の理由によれば、

他方,この点に関する被告人の主観面をみると,被告人は,本件Winnyを公 開,提供するに際し,本件Winnyを著作権侵害のために利用するであろう者が いることや,そのような者の人数が増えてきたことについては認識していたと認め られるものの,いまだ,被告人において,Winnyを著作権侵害のために利用す る者が例外的とはいえない範囲の者にまで広がっており,本件Winnyを公開, 提供した場合に,例外的とはいえない範囲の者がそれを著作権侵害に利用する蓋然 性が高いことを認識,認容していたとまで認めるに足りる証拠はない

「例外的とはいえない範囲」とは一体どういった状態をいうのであろうか。たとえばThe Pirate Bayだ。The Pirate Bayは親切にもランキングを出してくれている。もっともランキングの高いtorrent Top 100を見ると、どうもタイトルやファイル名からして、ほとんど違法ファイルではないかと思う。もちろん、上記のマグネットリンクはThe Pirate Bayから直接コピペしてきたものなので、中には合法ファイルへのリンクもある。結局、The Pirate Bayがどんなファイルへのリンクでも受け付けるので、こうなっているのだが、はたしてどうなるのか。

かといって、Winnyだって、違法な目的に使われた場合のほうが多いはずだ。Winnyですら「例外的とはいえない範囲」の著作権侵害の割合であるとすれば、The Pirate Bayもそうなのであろうか。とすると、幇助ではないのだろうか。

思うに、今の技術に、法律どころか、我々の常識すら追いつけていないのではないだろうか。もちろん、私は楽観主義者なので、二、三十年ほどすれば、いまの問題はすべて白黒ついているのではないかと思う。もちろんその時は、また別の問題が出てきているだろう。たとえば、「家庭用3Dプリンターを使ってXBox5760やPS7やiPhone 16を印刷するのは合法か」とか、「電子化されてシミュレーション再現された故人に対する人権」とか。

参考文献:
BitTorrent Site The Pirate Bay Turns Away From Torrents
The Pirate Bay
The Pirate Bay - Wikipedia, the free encyclopedia
BitTorrent (protocol) - Wikipedia, the free encyclopedia
BitTorrent tracker - Wikipedia, the free encyclopedia
Torrent file - Wikipedia, the free encyclopedia
Magnet URI scheme - Wikipedia, the free encyclopedia

C++11ですみやかにプログラムの実行を終了する方法

結論:C++11で新しく追加されたstd::quick_exitを使え。

プログラムの終了は、すみやかに行われるべきである。なにしろ、終了なのだ。終了にもたついていてはストレスがたまる。とくに、多くの実行環境では、プログラムの外部から、プログラムを強制終了させる方法がある。強制終了は大抵、プログラムの意志を無視して、強制的に一瞬で行われる。外部からできるのであれば、内部からできてしかるべきである。

なぜプログラムは終了時にもたつくのか。それは、終了時に特別な処理を必要とする場合もあろう。たとえば、数GBものデータを遅いHDDに書きださねばならない場合もあるだろう。これは妥当な理由である。では、確保したメモリやその他のリソースの解放処理はどうか。これは、疑問である。というのも、多くの近代的なOSでは、プログラムは個々に独立している。プログラムには独自の仮想メモリ空間が与えられ、必要に応じて物理メモリが割り当てられ、その他のリソースも独自に確保される。他のプログラムとは区別される。もし他のプログラムとリソースを共有したい場合は、なにか特別な方法を使わなければならない。そして、あるプログラムが確保したリソースは、そのプログラムの終了時に、OSが自動的に解放するようになっている。

プログラムの実行中に、必要のないメモリその他のリソースを解放せずに、延々と確保し続けるのは、これをリソースリークと呼ぶ。しかし、終了時には、どうせOSが解放してくれるのだから、自分でやるのは無駄である。

ここで未熟なプログラマー読者は思うであろう。解放するのがプログラムにしろ、OSにしろ、どちらかがやらなければならないのだから、どちらがやっても同じではないか。もし、プログラムによる解放が、OSに比べて極端に遅いとすれば、それは欠陥ではないのかと。問題は、ひとつのリソースを解放するというほど単純ではない。

例えばメモリだ。近代的なプラットフォームでは、仮想メモリ空間に割り当てる物理メモリはページ単位で確保する。これはたいてい、数KB単位である。しかし、現実のプログラムでは、もっと少ない単位(数十バイト)のメモリを大量に必要とする。これに対し、数KB単位のメモリを割り当てていたのでは、無駄である。そこで、現実には、まず一括してある程度の量のメモリを確保しておき、メモリ上に管理のためのデータ構造を構築し、そのメモリを必要とする小さな単位に切り分けて使う手法がとられる。これをヒープと呼ぶ。プログラムの実行中は、このヒープ内のメモリの確保と解放の処理は意味がある。しかし、プログラムが終了するのであれば、そんな処理は必要ない。ある仮想メモリ空間に割り当てられている物理メモリをすべて解放し、その仮想メモリ空間も破棄すればよい。これはすぐ終わる。ところで、近代的なプログラムであれば、マルチスレッドを使うのは当然である。ヒープに対する操作は、スレッドセーフではない。よって、ヒープの操作には排他的なロックをかける必要がある。プログラムの終了時に、すべてのスレッドが確保していたヒープ上のメモリを一斉に解放しようとしても、ヒープに対する操作は排他的であるので、いかに多数のCPUを搭載していようと、パフォーマンスは全くスケールしない。ましてや、ヒープ上のデータ構造の状態は、ヒープごとすべて破棄する場合には、全く関係ないのだ。結果として、遅くなる。

近代的なOSでは、ファイルやネットワークソケットなどといったその他のリソースには、リソースに対するハンドルが与えられる。リソースへの操作は、このハンドルを介して行われる。実行時に動的な数のリソースを確保するプログラムは、動的な数のハンドルを格納できるデータ構造を使う。一方、OS側でも、ハンドルと実リソースと紐付けるために、何らかの動的なデータ構造で情報を保持して置かなければならない。プログラムが明示的にすべてのリソースを解放する場合、プログラム側のデータ構造を巡り巡って、すべてのハンドルに解放処理を行う。ハンドルに対する解放処理を要求されたOSは、これまたOS側のデータ構造からハンドルに該当する実リソースを探し出し、解放処理を行う。しかし、最初から全てを解放するのだと分かっているならば、プログラム側の処理は二度手間である。

そう、ただちに終了するのであれば、プログラム側は何もしないほうがいいのだ。ところが、近代的なプログラミング言語では、「何もしない」というのは難しい。たとえば、C++にはクラスという機能がある。クラスにはコンストラクターとデストラクターがあり、これは、クラスの構築時、破棄時に、自動的に実行される。

C++においてプログラムを終了させる一般的な方法とは、main関数からのreturnである。しかし、main関数からreturnするためには、ネストして呼び出しているすべての関数からreturnしなければならない。

class X
{
    X() { /* リソースの確保 */ }
    ~X() { /* リソースの解放 */ }
} ;

void f1()
{
    X x ;
    // さあ、終了しよう
    return ;
}

void f2()
{
    X x ;
    f1() ;
    return ;
}

int main()
{
    X x ;
    f2() ;
    return ;
}

この例で、関数f1の中身を実行中に、プログラムを終了させたい場合、ネストされた関数を延々とreturnしなければならない。そればかりではなく、スコープの離脱に伴い、クラスXのローカル変数のオブジェクトxのデストラクターを走らせなければならない。たとえ、デストラクターの処理が、単なるリソースの解放であったとしても、デストラクターの実行を止めることはできない。

C++には、Cから受け継いだstd::exitがある。これを使えば、その場で終了できる。exitを呼び出した後に実行が続くことはない。ところが、このexitにも問題がある。グローバル変数とスレッド変数の破棄が実行されてしまうのだ。

X x1, x2, x3 ;

void deep()
{
    std::exit(0) ; // x1, x2, x3, x4のデストラクターが実行される
}

void f()
{
    thread_local X x4 ;
    deep() ;
}

int main()
{
    f() ;
}

では、終了中かどうかを判定するフラグを作って、すべてのグローバル変数とスレッド変数のデストラクターにチェックさせるべきなのだろうか。それでは、自動的なデストラクターの実行の意味がない。

他にも、C++11には採用されなかったが、他の言語では、ガーベージコレクションなどがある。これも速やかな終了の妨げになる。

多くのプラットフォームでは、プログラム自身の終了を止める独自APIが提供されている。プログラムのすべてのスレッドの実行を問答無用で停止して、終了処理を行うようなAPIだ。特定のプラットフォームだけを考えればいいのならば、そういうAPIを使えばいい。しかし、ポータブルなC++のコードを書く場合、できるだけそのような独自APIには頼りたくない。何故ならば、サポートするプラットフォームの数だけ、別々の実装が必要になるからだ。

C++11では、この状況に鑑み、std::quick_exitを用意した。使い方は、std::exitを全く同じだ。違いは、グローバル変数やスレッド変数の破棄が実行されないこと、Cのファイルストリームのフラッシュが行われないこと、終了前にstd::at_quick_exitで登録した関数が呼ばれることだ。

したがって、近代的なプログラムの終了手順は以下のようになる。

  1. 必要であれば、std::at_quick_exitでプログラム全体の終了処理を行う関数を登録する(プログラムの内部バッファーの書き出しなど)
  2. その場で終わらせるべき処理を速やかに終わらせる
  3. Cファイルストリームを使っていて書き込み結果が反映されて欲しいのであれば、フラッシュする
  4. std::quick_exitを呼び出す