増井ラボノート コロンブス日和

第14回HashInfo

HashInfo

次のような作業をやりたいと思ったことはないでしょうか?

  • 同じファイルがあちこちにないかチェックしたい
  • 重要なファイルだけバックアップしたい
  • 自分のアイデアを日付つきで記録したい

実はこのような仕事は、1つの単純な方法を使って実行できます。

パソコンやWebには膨大なファイルがありますが、同じファイルがあちこちに冗長に置かれていることも多いでしょう。

私の場合、同じファイルを何度もダウンロードしてしまったり写真や動画をいろんな場所にコピーしてしまったりすることがよくありますし、バックアップのつもりでコピーしたデータをさらにバックアップ対象にしてしまった結果、バックアップのバックアップ(のバックアップの……以下同様)のような無駄なデータを作ってしまうことすらあります。

こういう問題を防ぐためには、同じファイルがすでに別のところに存在するか調べれば良いわけですが、すべてのファイルの中身を比較することは現実的ではありません。しかし、ファイルの「ハッシュ値」を利用すれば、あるファイルが独自の(ユニークな)ものなのかどうかを比較的簡単に判別できます。

ハッシュ関数とハッシュ値

デジタルデータを一定サイズの数値に変換する関数をハッシュ関数と呼び、計算された値をそのデータのハッシュ値と呼びます。

最近のプログラミング言語ではa['abc']のような連想配列が使えるのが普通ですが、これを通常の計算機上に実装する場合、"abc"のような文字列に対してハッシュ関数を計算し、その数値を添字として利用することによって通常の配列と同じように扱う手法がよく利用されています。

ハッシュ値のサイズが小さい場合は、異なるデータから同じハッシュ値が計算されてしまう(ハッシュ値が衝突する)ことがありますが、ある程度大きなハッシュ値を生成する適切なハッシュ関数を用意すれば、ハッシュ値が衝突する可能性はほぼゼロにできます。また、ハッシュ値からもとのデータを計算することもほぼ不可能にできます。

ハッシュ関数はさまざまなものが考えられますが、現在はMD5やsha1というハッシュ関数が広く利用されています。このようなハッシュ関数は次のような特徴を持つため、暗号化アルゴリズムなどで広く利用されています。

  • ハッシュ値からもとのデータを知ることはできない
  • 異なるデータのハッシュ値が同じ値になることはない

ファイルデータから計算されるハッシュ値の情報(HashInfo)をうまく利用することにより、最初に述べたようなさまざまな有用な機能を実現できます。

重複ファイルの視覚化

ハッシュ値の特徴を利用すれば、手持ちのすべてのファイルのハッシュ値をあらかじめ計算しておくことにより、あるファイルが別のところにすでに存在するかを調べることができます。たとえば、movies/abc.mp4という動画とbackup/xyz.mp4という動画のハッシュ値が同じであれば、abc.mp4xyz.mp4は同じファイルだということがわかるので、たとえば両方をバックアップする意味はないと判断できます。

図1は、手持ちのパソコンのすべてのファイルのハッシュ値を計算し、それをTreemapという手法で視覚化してみたものです。同じファイルが複数ある場合、そのファイルを赤く表示しています(研究室に所属していた池滝俊太氏の卒業論文による⁠⁠。

図1 自分のパソコン内で重複しているものを赤く表示したもの
図1 自分のパソコン内で重複しているものを赤く表示したもの

池滝氏は整理が得意なのか、重複するファイルは多くはないようですが、それでもかなりの部分に色がついている(ファイルが重複している)ことがわかります。

ハッシュ情報を複数の人間で共有すれば、自分が持っているファイルを他の人も持っているかどうかがわかります。図2は、研究室の数人の学生に協力してもらって、他人のパソコンまで比較対象を広げて同じ計算をしてみたものです。多くの学生はMacを利用しており、Macのシステムファイルは全員に共通であるため、図1に比べると左下部分が赤くなっています。

図2 他人とのファイル共有の視覚化
図2 他人とのファイル共有の視覚化

このように、ハッシュ関数を利用すると自分が持っているファイルの素性がなんとなく見えてくると言えるでしょう。ファイルの中身をいくら調べてもこういうことはわからないわけですが、他のファイルや他人のファイルとの比較によりファイルの特徴が見えてくることになります。

重要情報のバックアップ

前述の方法を使うと、複数のマシンでHashInfoを計算することによって、さまざまなマシンで同じファイルが共有されているかどうかがわかります。システムファイルやメジャーなアプリケーションのファイルは多数のマシンで共有されているはずですが、あまり重要でない大きなファイルでもいろんなマシンで共有されている可能性があります。

たとえばNode.jsでプログラム開発をする場合、node_modulesというフォルダの下にたくさんのライブラリがダウンロードされますが、このようなファイルはバックアップをする必要はありません。

ブラウザでWebからデータをダウンロードするとき、大きなアプリケーションのプログラムファイルも重要なファイルも同じフォルダに入ってしまい、広く配られているファイルと重要なファイルを区別することは困難ですが、HashiInfoを利用するとその違いが明白になるので、どのファイルが重要なのかがわかるようになります。

一方、コンパイル結果やログファイルなどは重要ではないにもかかわらず、他人が同じファイルを持っている可能性は低いと思われます。

「他人と共有していない」⁠自動生成されるファイルではない」といった条件を満たすファイルは重要である可能性が高いので、こういう性質をもつファイルだけをバックアップすることにしておけば、無駄なバックアップを防ぐことができるでしょう。

ファイルの存在証明

特許や論文になるかもしれない新しいアイデアを思いついたときなど、ある時点においてある情報を自分が持っていたことを証明したい場合があります。

情報がいつ作成されたかを個人的に覚えておくためにはファイル作成時刻を記録しておけば良いのですが、ファイルの中身や作成時刻は後から偽造できるので、確かにその時点でその情報が存在したということを他人に納得させることはできません。デジタル情報がいつ作成されたか証明するためには、信用できる外部の誰かに認証してもらう必要があります。

ある時点である書類が存在したことを証明するためには昔から公証役場が利用されています。公証役場の業務の1つに「確定日付の付与」というものがあります。これは、私文書に「確定日付」を付与し、その日付にその文書が存在したことを証明するものです。

デジタルデータを印刷して書類にしておけば、その存在を証明するために公証役場を利用できますが、情報を印刷して公証役場に持って行くのは面倒ですし費用もかかります。

最近はデジタル情報の存在を証明するために電子公証システムを利用できるようになったので、公証役場に行かなくても公的な認証を得られるようになりました。これは朗報なのですが、かなりの費用がかかるのが難点です。

ある時刻にあるデジタルデータが存在したことを証明する技術のことをデジタルタイムスタンプ技術と言います。電子公証システム利用は高価であり利便性の問題もあるので、Seikoアマノのような会社がデジタルタイムスタンプ技術を提供するサービスを提供しています。

しかし、大事なデータを民間企業に渡すのは心配ですし、サービスがどれほど信頼できるかわかりません。実際、現在運営を中止してしまったサービスもありますし、10年後/20年後も確実に利用できる保証はありません。

電子公証システムや民間の証明システムを利用する場合は証明したいデータの提示が必要ですが、情報が漏れることは心配かもしれません。その時点でその情報が存在することは証明したいけれども情報の中身は公開したくないかもしれません。簡単で良いアイデアを思いついたときなど、特許をとるまで内容は誰にも公開したくないでしょうが、そのアイデアを自分が思いついた日時については記録しておきたいでしょう。

つまり「情報を持っていることは証明するが、情報そのものは公開しない」方法が必要になります。

HashInfoによるデジタルタイムスタンプ

生のデジタル情報の存在証明を行う代わりに、その情報のハッシュ値の存在証明を行うことにすれば、情報そのものを渡す必要がないのでより安全だと考えられます。

たとえばある問題の解法を発見したとき、たとえば「問題AはBという方法で解決できる」といった文字列のハッシュ値を公証役場や電子公証サービスに登録しておけば、ハッシュ値からもとの文字列を計算することはほぼ不可能なので、文字列そのものを登録しなくても証明を行うことができます。

電子公証サービスや民間のデジタルタイムスタンプサービスを利用しなくても、一般的なブックマークサービスやブログサービスを利用することによって無料でハッシュ情報の存在を証明できるかもしれません。

たとえば秘密情報のハッシュ値がABCDEFという値になるとき、http://example.com/ABCDEFというURLをはてブのようなブックマーク登録サイトや任意のブログサービスに記録しておけば、ABCDEFという情報がどの時点で存在していたかがそれらのサイトで公開されることになりますから、Aという問題を解くための情報が、ある時点で存在したことが証明されることになります。

1つのサービスだけに登録すると、そのサイトの管理者に偽造される可能性もあるでしょうが、関連のないたくさんのサービスに同じ情報を登録しておけば、すべてを偽造することは不可能と考えられるので、その情報がその時間に存在したことをかなり確実に主張できると思われます。

つまり、時刻を証明したい情報があるときは必ず次の手順をとることにしておけば、確実にデータの存在証明を行うことができるでしょう。

  • 情報を秘密の場所に格納する
  • 情報のハッシュ値を複数のサイトに登録する

普通のテキストエディタを使っている場合でも、気合いを入れてセーブした場合には上記の処理を自動的に行うようにしておけばいいかもしれません。秘密にしておくべき元データを安全な場所に格納しておけば良いでしょうし、暗号化したデータをクラウドなどにもセーブしておけばさらに安全かもしれません。

HashInfo.net

今回はHashInfoを利用する3種類のアプリケーションを紹介しましたが、多数の人間でファイルのハッシュ値を共有するデータベースがあればさまざまな用途に利用できることが期待できるので、誰もがHashInfoを活用できるようにするためのHashInfo.netというサイトを運用したいと考えています。

一方、こういうサービスではプライバシーの問題に気を付ける必要があります。素性が怪しいファイルを他の誰かが持っていることがわかれば問題になる可能性もありますし、⁠名寄せ」的に個人が特定される可能性があるので、誰がどのハッシュを持っているかという情報は十分に注意して扱う必要があるでしょう。しかし、プライバシーやセキュリティに十分配慮すればHashInfoが有用な機会は多いはずです。

Googleは、ファイルの中身よりもファイル間のリンクを重視することで検索精度を向上させることに成功しましたが、ファイルの中身よりもファイルの重複を重視することによって大きな効果を得られる可能性もあるでしょう。HashInfo.netの運用などによって有益なシステムを構築できればと考えています。

Software Design

本誌最新号をチェック!
Software Design 2022年9月号

2022年8月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)

  • 第1特集
    MySQL アプリ開発者の必修5科目
    不意なトラブルに困らないためのRDB基礎知識
  • 第2特集
    「知りたい」⁠使いたい」⁠発信したい」をかなえる
    OSSソースコードリーディングのススメ
  • 特別企画
    企業のシステムを支えるOSとエコシステムの全貌
    [特別企画]Red Hat Enterprise Linux 9最新ガイド
  • 短期連載
    今さら聞けないSSH
    [前編]リモートログインとコマンドの実行
  • 短期連載
    MySQLで学ぶ文字コード
    [最終回]文字コードのハマりどころTips集
  • 短期連載
    新生「Ansible」徹底解説
    [4]Playbookの実行環境(基礎編)

おすすめ記事

記事・ニュース一覧