自作プログラム履歴書

これまで個人で作成したプログラムを紹介します。

その他にもここで紹介しきれなかったプログラムはGitHubに公開しています。

Github: coolandsmartrr

スマートチケット

Source Code

ブロックチェーン上で認証するイベントチケットシステムを作成しました。主にコンサートなど催し物の入場での使用を想定しています。これまでチケットには転売問題があり、いわゆる「ダフ屋」が規定価格を上回る高額で販売している問題がありました。紙に印刷されたチケットは枚数や所有者によって物理的に入場者を制御していますが、紙のチケットは譲渡が容易であり、不正販売を防ぐことが難しいです。

そこでブロックチェーンの起用を考えました。ブロックチェーンは誰もが運営・認証できるデータベースであり、不可逆的な暗号処理を使用しているため記録の改竄が極めて難しいです。Ethereumという帳簿項目の設定などのプログラミングが容易なブロックチェーンを使用し、電子チケットの帳簿を試験的に運営しました。電子チケットには所有者の情報・譲渡権利・譲渡条件などが記載されており、イベント主催者の許可なく譲渡することはできません。

このプロジェクトでは、実際に芸能事務所を訪問し、タレントマネージャーの方にヒアリングを行いました。ヒアリングでもっとも難しかったところは暗号処理についての説明であり、新しい仕組みの普及のためには利用者に分かりやすい説明が不可欠だと痛感しました。

Safecast-on-IPFS

Source Code

P2Pのネットワークで半永久的にデータを保存する方法とその情報の正確性を認証する方法を考案しました。データには保守性の問題があります。例えば、データをホスティングするサーバーがネットワークから切断されたら、そのデータの住所であるURIから以後データを取得できなくなります。(300系のHTTPリスポンスコードなどによって)転送先が案内されていたら無事にデータをアクセスできますが、サーバーの運営者がその類の例外処理を丁寧に対処されているとは限りません。場合によっては、外部からアクセスできるサーバー領域からデータが消失していることもあります。外部のサーバーがそのデータを複製していたら、そのデータを改めて取得することが可能ですが、2つの問題が浮上します。

  1. URIの検索にかかる手間
  2. データの正確性

(1)については、ユーザーがインターネット上でその他のURIを探す必要があり、世間的に関心の低いデータは代替となる所在地が広く告知されてないため、新たなURIの検索に時間と工数が掛かります。

(2)については、仮に代替となるデータ提供元を確保しても、データの正確性が保証されないことを指します。データの転送過程におけるデータの破損や、新しいホストによるデータの改竄などの可能性があります。

これらを解決するため、2つの解決方法を提案しました:

(1) 特定のサーバーに依存しないP2Pのネットワーク上でデータを公開し、不可変なURIでアクセス可能にすること。URIはデータの「確認番号」であるハッシュ値で存在するため、WebのURLスキームのようにアドレスを変更されることがありません。

(2) ビットコインのブロックチェーンにデータの「確認番号」となるハッシュ値を記載し、その時点でデータがその形で存在していたことを証明すること。 ビットコインのブロックチェーンは「ブロック単位」で管理されていますが、ブロックのデータ構造として「コメント欄」が80バイトほどあります。そこにメルケルツリーというデータ構造でアップロードするデータのハッシュ値を並べ、2つずつのハッシュ値を算出し、最終的にツリーの頂点に立つハッシュ値を「ブロック」に記載しました。これでどれだけファイルがあってもコンパクトにハッシュ値を算出することができます。また、ユーザーの手元にメルケルツリーの「証憑」データがあり、第3者が正確性を検証できるようになっています。

データは日本国内の放射能データ収集して誰でも利用可能にしている団体であるSafecastのものを使いました。幸いSafecastの運営状態は透明性が高いのでデータ消失の懸念はないですが、貴重な歴史データが元のサーバーから消失した実例があります。例えば、トランプ政権時に米国政府の国環境保護庁のサーバーから過去の環境データが消失しました。このように、データの運用方針・提供方法・ガバナンスなどがデータの保守性に強い影響を及ぼします。

大学の卒業論文として制作しました。論文はGitHubに公開しています。

VR森林浴

(ソースコードは前のPCから復元次第、共有いたします)

Unityで無限に森林が生えてくるVR環境を作成しました。ヘッドマウントディスプレイやなど画像処理の仕組みについて学ぶことが多かったです。また、3D環境を瞬時にレンダリングするための最適化に苦労し、遠くにある物体をビルボード化するなどのレンダリングテクニックに触れることができました。

また、VR森林浴によるユーザーへの心理作用を測定しました。心理テストで被験者のストレス度を以下のタイミングで測りました。

  1. 実験前
  2. 数学問題によるストレス負荷後
  3. VR森林浴の使用後

数学問題解答後にストレスの上昇、およびVR森林浴の使用後にストレスの軽減が観測できました。

VR作品づくりの経験を活かし、関係者にVRについての的確な取材をすることができました:

研究会での発表資料を添付いたします。

(同ディレクトリに"最終発表.pptx"として格納)

InstaFollow

Source Code

Instagramでフォローしているアカウントを別のアカウントにエキスポート・インポートするプログラムです。週末に手っ取り早く制作したく、学習コストを減らすため、豊富なドキュメンテーションで人気なSeleniumフレームワークでWebブラウザーの挙動を自動化しました。本来は公式のAPIを使用したかったですが、FacebookがCambridge Analyticaによる騒動を受けて、自社が提供するサービスに対して書き込めるAPIの提供を終了していました。Instagramサーバーのボット対策により429 Too Many RequestsのHTTPエラーがプログラム動作時に発生したため、アクセス頻度を乱数で調整して制約を回避しました。

HTTP Server Code in C

(ソースコードは前のPCから復元次第、共有いたします)

学習目的にC言語でHTTPサーバーを作成しました。80番ポートのアクセス・解放・待機などの手順をこちらで全て実装しました。


おまけ

好きなプログラムやアルゴリズムを紹介します

Quake 3 Arena - Fast Inverse Square Root

Source Code

ジョン・カーマック氏を筆頭とするid softwareの技術力は業界で話題を呼びますが、「Quake 3 Arena」がオープンソースで公開時に、平方根の逆数を迅速に算出するアルゴリズムが注目を集めました。ゲームグラフィックスの計算時にはベクトルをノーマライズする必要があるため、このような計算が頻繁に起きます。このアルゴリズムでの算出値は概算であるものの、ゲームには十分実用的であり、処理速度の向上をもたらします。

通常、平方根の逆数の算出には以下のようなコードを書きます:

#include <math.h>
float y = 1/sqrt(x);

しかし、割り算の実行は比較的に時間がかかります。代わりに「Quake 3 Arena」では以下のようにコードが記載されていました:

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                        // evil floating point bit level hacking
    i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//    y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

    return y
}

最初の変数はlong型ですが、メモリには32ビットの数値として格納されています:

 00000000 00000000  00000000  00000000 

次の変数であるfloat型はIEEE 754で以下のように定義されています:

0 (+/-ビット)00000000 (指数ビット (2^n-127))00000000000000000000000 (仮数ビット)

float型の変数はビットシフト操作ができませんので、変数が格納されているメモリのアドレスをポインタとして渡してlong型として読み取ります:

    i  = * ( long * ) &y;

その後、i >> 1で左にビットシフト操作を行い、変数の値を倍増します。0x5f3759dfからその値を引くことで誤差を縮めることができます。

    i  = 0x5f3759df - ( i >> 1 );

上記の概算値をfloat型の変数yに格納します。

    y  = * ( float * ) &i;

次は、ニュートンの方法で誤差をさらに縮めます。ニュートンの方法では、とある$x$から$f(x)$とそれの導関数である$f'(x)$で$f(x)/f'(x)$を算出し、元の$x$から$f(x)/f'(x)$を引きます。

Newton's Method

approximation1 = x - f(x)/f'(x)

error(x) = x^-2 - i

approximation2 = x - error(x)/error'(x)

= x - (x^-2 - i) / (-2x^-3)

= x(1.5 + 0.5ig^2)

ソースコードでは、ニュートンの方法がこのように記載されています:

    y  = y * ( threehalfs - ( x2 * y * y ) );
    // Editor's Note: x2 is 0.5 of float variable "number"

Wii センサーバーの代替方法

学生時代のスキー合宿で友人がWiiを持ってきましたが、彼がセンサーバーを家に忘れたので、メニュー画面で起動したいゲームをWiiリモコンで指すことができず、ゲームソフトに遷移できませんでした。しかし、センサーバーは赤外線を出力していると知っていましたので、代わりに赤外線を出力できるライターを(火災予防の面から)システムのメニュー画面が出た時だけ使用して、無事に「大乱闘スマッシュブラザーズX」を起動し、その後はみんなで楽しむことができました。発案者の私は試合に負けても次のラウンドに参加させてもらうことができました。