• 締切済み

ハッシュの考え方、使用例を分かり易く教えてください。

基本情報処理の勉強をしていますが、ハッシュの考え方がいまいちわかりません。分かり易く教えていただけると幸いなのですが、どなたかご教授いただけませんでしょうか。どうぞよろしくお願い致します。

みんなの回答

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.4

ハッシュ関数と言うのが考えられていて http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0 にあるように 暗号化 誤り検出 改ざん検出 ハシュテーブル などに使われます。 ハシュという時、どの関連を言っているかか注意しましょう。 データベース構成と検索に関連して述べてみます。 例えば口座番号が7桁あるとします。ディスクに1千万区画の記録区画を用意すれば、どんな口座番号が来ても、その数字番目の区画に記録できます。 しかし口座番号に空きがあって、実際は100万口座しか使われてないとき、ディスクに100万区画を用意しておき、ある口座番号が来た時に、もし100万の中に散らばって、記録場所が決められれば、能率的です。 F(口座番号数字)=数字 Fは何か計算すること(関数)を意味します。 特徴は口座番号数>>数字(>>は相当少ない意味)でないと意味を持ちません。 そして口座番号数字が色々変ってはいってきた場合、数字は別のものになることが望ましい。なぜなら重複する数字になると、後からの口座の記録場所がなくなるから。 さてそんな関数Fがあるかどうか。 http://ja.wikipedia.org/wiki/%E4%B8%80%E6%96%B9%E5%90%91%E6%80%A7%E9%96%A2%E6%95%B0 にある一方向性関数と言うのが研究されています。 これの良いところは、計算で「数字」が出て、そこに記録されていることが決まっているから、そこだけを見に行けば良く、速く探しやすい。 目次インデックスを使うようなのは、何段もディスクをアクセスして辿らないと行けないのに比べて速い。 ディスクのファイルを読む時間>>場所を計算する時間。 http://www.db.is.kyushu-u.ac.jp/adp/ad/hash.pdf の配列による探索とハッシュ法に当たります。 しかし衝突は避けられず、衝突するケースを5%とかに押さえて設計し、衝突すれば別の区画にお引取り願うように 設計する。 例えば123、345、231、345があるとしてそれぞれに何かの演算をして1,2,3,4の数字を出せれば 一番良いのですが。 長くなるので、一端を記してみました。 Hashは「肉を切り刻む」「メチャメチャにする」「(フランス古語の)斧」から来ておるそうです。 MOD関数などを使って、出した結果の数が元の数・原型を窺えないところからでしょうか。

全文を見る
すると、全ての回答が全文表示されます。
  • GoF
  • ベストアンサー率37% (34/91)
回答No.3

教えるために、非常にシンプルに考えます。 例えば、以下の文章をハッシュにしてみます。 きょうは いい天気 あしたも いい天気 だといいな。 これを縦読みして、「きいあいだ」これがハッシュ値です。 縦読みを実装している関数をハッシュ関数といいます。 ちなみに、実際のハッシュ関数は戻り値は数値に変換 されていますし、もっと賢い関数ですのでご注意ください。

全文を見る
すると、全ての回答が全文表示されます。
noname#30727
noname#30727
回答No.2

ハッシュに進まれているということは、既に幾つかの探索やソートは知っていますよね。 探索やソートする為には比較が必要です。ところが、比較対象が大きいデータの場合、比較そのものに時間がかかってしまいます。例えば、1024バイトのオブジェクトの比較には、最大1024バイトの比較が必要です。 この大きなデータの比較を一意な整数の比較で済ませる事ができれば、比較時間を大幅に短縮できると考えた人がいます。これがハッシュという考え方の始まりです。文字列を取り扱うときによく使用されます。 以前に自作コンパイラのコンパイル速度の比較をしてみた時の事ですが、バイナリーサーチとハッシュ法の速度差は、前者で1分かかるものが、後者だと1秒以内に終わります。 不思議なことに、実利でこれほどの違いがあるにもかかわらず、ハッシュ法を理解している人はそれほど多くはいません。 試験の為という事ではなく、この辺をきちんと理解しておくと「出来る人」と扱われます。

全文を見る
すると、全ての回答が全文表示されます。
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

1.ハッシュとはある文字列からある数値(これをハッシュ値といいます)をある規則に従って作成する事です。 2.その場合、同じ文字列は必ず同じ数値(何時の場合でも)に変換されることが必要です。 3.この例を示します。話しを簡単にするために、文字列はA~Zだけで構成されていることにします。 AAA, ABB, AAADD, BAB, B これらの文字をハッシュ値に変換する為には、上記の2の条件を満足する変換の規則を決めれば良いわけです。 例えば、先頭の1文字だけに注目するとA~Zになります。 これをA->1、Z->27のように割り当てるとします。そうするとAAA->1,ABB->1,AAADD->1,BAB->2,B->2 のような値が作成されます。これは立派なハッシュ値になります。なぜなら、上記の2の条件を満足していますから。しかしながら例えば、現在の時刻(秒)をこの値に加えたものは、ハッシュ値にはなりません。(毎回同一の結果が得られないため) 4.実際のハッシュ値の作成方法は、これほど単純ではありません。例としては、以下のようにします。(但し、この方法が良く使われているわけではありません。あくまでも例です) 各文字を上記の数値に変換した結果を掛け合わせ、その値を10000で割った余りをハッシュ値とします。 AAA->1×1×1/10000の余り=1 ABB->1×2×2/10000の余り=4 のようになります。 この方法でも必ず、同一の文字列に対しては、同じ結果が得られます。尚、異なる文字から同じハッシュ値が生成された場合、これをシノニムと呼びます。 ABB->1×2×2/10000の余り=4 ABBA->1×2×2×1/10000の余り=4 はこの場合、シノニムが発生した状態となります。 4.以上がハッシュ値を作成する方法でした。 では、このハッシュ値をどのように利用するかということですが、文字列の検索を高速で行う場合に利用します。 5.文字列の検索方法は、以下の3通りがあります。 1)シーケンシャルサーチ 2)バイナリーサーチ 3)ハッシュ値による検索 上記の1)2)はここでは、説明を省略します。(判らないときは補足して下さい。そのときは改めて説明します) 例として、10000件のデータがあるときの検索回数は 1)シーケンシャルサーチは平均5000回の検索 (最良で1回、最悪で10000回) 2)バイナリーサーチの場合は、平均13~14回の検索 となります。 では、ハッシュの場合は、どうなるかということですが、それにはまず、ハッシュ検索がどのようなものかを知る必要があります。 5.ハッシュ検索の手順は、以下の手順で行います。 1)文字列からハッシュ値を作成する。 (先頭の1文字をA~Zを1~27にする方法とします) 2)そのハッシュ値が示す場所へその文字列を格納する。 例えば、AAA->1のハッシュ値の場合、1番目の配列にAAAを格納します。 BBB->2の場合、2番目の配列に格納します。 ABB->1は、シノニムですので、1番目に格納したいが、既にAAAが格納されているので、1番目のシノニムを格納する別のテーブルを作成し、そこに格納する。 そのようにして文字列をテーブルへ格納していきます。 3)検索は以下のように行います。 ・検索対象の文字列からハッシュ値を求める。 ・求めたハッシュ値に示されるテーブルの位置を検索する。 ・そこに存在しなければ、シノニムを格納してあるテーブルを検索する。 ・そこにも無ければ、該当文字はない。 6.以上がハッシュ値による検索です。 従って、ハッシュ値による検索時は、以下のことが大切になります。 1)ハッシュ値を求めた時に、シノニムの発生がすくないこと。(この数が多いと検索回数が増えます) 2)では、どうすればシノニムの発生が少なくなる方法で、ハッシュ値を作成するかということですが、これはデータの集団がどのようなデータ構成をしているかにも依存します。従って、これと言う切り札はありませんが、いろいろと工夫する必要があります。 7.理想的には10000万件のデータから1~10000のハッシュ値を作成し、シノニム無しであれば、1回の検索ですみます。A~Zを1~27にする方法では、良くても10000/27=370のシノニムが発生し、約370/2回の検索回数となります。最悪は、(全てAから始まる文字列の場合)シーケンシャルサーチと同じ結果となります。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ハッシュのハッシュのソート

    rubyでハッシュのソート方法についてはいくつか情報のサイトを見つけられました。 ですが今やりたいのは、ハッシュのハッシュのソートなのですが、うまいやり方がわかりませんでした。 具体的には、 h1 = {"user1"=>{"a"=>10, "b"=>20, "c"=>30"}, "user2"=>{"d"=>5, "e"=>8}, "user3"=>{"f"=>10, "g"=>5, "h"=>10} } というようなハッシュのハッシュを想定しています。ユーザごとに案件ごとの必要工数(時間)をハッシュとして持たせ、全工数が多いユーザ順にソートしたいのです。 上記の場合だと、 {"user1"=>{"a"=>10, "b"=>20, "c"=>30"}, "user3"=>{"f"=>10, "g"=>5, "h"=>10}, "user2"=>{"d"=>5, "e"=>8} } というようにソートしたいのですが、何かやり方がありましたらご教授いただけますでしょうか。

    • ベストアンサー
    • Ruby
  • 投票データをハッシュを使用して入出力する

    こんにちは。tyabudaiと申します。 アンケート(投票)のCGIを 作成しようと思っています。 ログの中身は、(とりあえずカンマ区切りで) 「項目,数値」です。 処理のイメージとしては、 まずログファイルの内容を、 「項目」をキーとしたハッシュに取り込みます。 投票があった場合、 「項目」をキーとして「数値」を取り出し、 1つ増加させる処理をしたいです。 現在、他サイト様よりCGIをダウンロードして そのような処理がないか探していますが、 全く手がかりがありません。 まずは、ログファイルの内容をハッシュに取り込む方法を お教えいただけないでしょうか。 ご存知の方のお力添えいただければ幸いです。

    • ベストアンサー
    • Perl
  • ハッシュ関数

    ハッシュ関数について悩んでいます. ハッシュ関数の例として以下Wikiの引用です http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0 unsigned int hash(char *s) { unsigned int h = 0; for (;*s != '\0'; s++) { h = h * 137 + *s; } return h % 1987; } このハッシュ関数において, 「hの更新計算で用いる137という数は、2(7乗)+2(3乗)+2(0乗) というものであり、乗法した後にも2進数表現の下位の桁にも 情報が残るようになっている。そのため前の方の文字の情報が 桁あふれによって失われることはない。」 と記述されているのですが,私が考えてしまうのは以下の通りです. 「最終的にハッシュ値は合計を1987で割った余りになるのだから, 下位の桁(1~1987)に情報を残さなければならない. それぞれのsの上位から下位までの情報を合計の数値の下位に 残すのであれば,137は掛けるのではなく割るべき.」 もちろん私の考え方が間違っているのはわかりますが, なぜ137を掛けるのかを理解できません. どなたかわかりやすくご教授いただけたら幸いです.

  • ハッシュ探索とはどういうイメージなのか?

    ハッシュ探索というのは「対象となるデータから一定の手順で算出したハッシュ値を用いてデータ本体の代わりに比較に用いる方式」ということですが、どういうものなのかイメージが思いつきません。 これはつまり、データ本体を「ハッシュ」という文字列に変換して、ハッシュ値として出力したものを、比較する(全ての文字列において比較する)というイメージでよいのでしょうか? もしそうだとしたら、ハッシュ値の長さ(文字列の長さ)に応じて(比較)処理時間が変わってくるのでしょうか? 例えば、(あくまで例です。) 6文字程度のハッシュ値→0.2秒で(比較処理時間が)終わる 3万文字程度のハッシュ値→3秒ぐらい(比較処理時間が)かかる ↑こういう風にハッシュ探索は文字列の長さに応じて処理時間が変化するのでしょうか? 回答のほうお願いします。

  • Perlでいうハッシュとはどのようなものでしょうか?

    パールを勉強しています。 ハッシュとはどのようなものでしょうか。

    • ベストアンサー
    • Perl
  • ハッシュ(メッセージダイジェスト)について

    よろしくお願いいたします。 現在セキュリティの勉強をしております。 で、ハッシュについて確認したく投稿いたしました。 自分なりに勉強をして、 送信者がデータをハッシュ関数を使用してメッセージダイジェストを 作成し、受けても同じ事を行うのはわかりました。 つまり、 [データ]+[メッセージダイジェスト(データに添付する)]+[デジタル署名(データに添付する)] の3点をまとめて暗号化し、 受け取った相手が秘密鍵で [データ]+[メッセージダイジェスト]+[デジタル署名]に複合し 自分でもハッシュ関数を使用してメッセージダイジェストを作成し 送り手のダイジェストと比較すると理解しましたが 正しいのでしょうか? また、同じハッシュ関数で自分でも作成するみたいですが どこにハッシュ関数の情報が載っているのですか? いまいち自信が持てませんのでアドバイスお願いいたします。

  • ハッシュとツリー構造

    今学校でハッシュとツリー構造について勉強しています。 しかし、先生の言っていることがまったく意味が分かりません。 すいませんが、ハッシュとツリー構造について簡単でいいので教えてください。 お願いします。

  • ハッシュテーブルの使い方

    こんにちわ。 いまVB.Net2003でプログラミングをしている者です。 ORACLEのあるテーブルの内容をハッシュテーブルに取り込んで, キー検索する処理をしたいのですが, 取り込む際,ハッシュテーブルの「Add」メソッドで 1件ずつ取り込むしかないのでしょうか? たとえばコンボボックスの「DataSource」プロパティに レコードセットを設定するように,一回で設定したいのですが, このような機能があるでしょうか? またハッシュテーブルはキーは1つしか設定できないようですが, このテーブルデータを2つのキーで検索するのはどうすれば 良いでしょうか?

  • phpのパスワードのハッシュ化について

    phpで会員サイトの作成を学習しています。 PDOを使用してMysqlサーバーに接続しています。 開発環境はxamppでphp Version 5.5.15を使用しています。 入力フォームにユーザーの情報を入力してもらい、 データベースに格納する際、 基本的なセキュリティ要件として パスワードをハッシュ化する必要があるということを こちらのサイトで(http://php.net/manual/ja/faq.passwords.php) 知りました。 ハッシュ化については初耳で、いまいちハッシュアルゴリズムの種類による違い等はまだ理解しきれていないのですが、 PHP5.5.15を使用しているので、パスワードのハッシュアルゴリズムは 上記サイトに載っているようにpassword_hashを使用するのが今のところ最善なのでしょうか? また、ハッシュ化されたパスワードの認証についてですが、 ログイン画面でパスワードを認証する際、 ユーザーが入力したパスワードをハッシュ化して 該当レコードのハッシュ化されて保存されたパスワードと 同じであれば認証が成功するという認識で正しいでしょうか? ご回答、よろしくお願いします。

    • ベストアンサー
    • PHP
  • ハッシュ関数について質問です。

    プログラミング・数学? 初心者です。 IDやパスワード管理によく出てくる一次方向(ハッシュ)関数ですが、 よくパスワードとSALTを一緒にしてハッシュ関数を通してハッシュ値を取得しますよね。 そしてその結果(データベースなどに記録済み)とログイン時に入力した値とを照らし合わせるわけですが、 昔まだ若いころ、これとは別のタイプのハッシュ関数を使用したことがあります。 それはある(パスワードなどの)値をハッシュ関数で処理すると「いろんなハッシュ値」が生成され、 そのハッシュ値から当然パスワードは予測できないのですが、 しかしその複数のハッシュ値は全て、そのパスワードから生成されたハッシュ値だということは分かる、という関数を使用したことがあります。 その時はperlのcpanモジュール(名前を覚えていません。すいません。)を使ったのですが、この別のタイプのハッシュ関数はどういう仕組みで作られているのでしょうか? SALTが複数あり、そのそれぞれについて照合している?だけでしょうか? それとも私が無知で、そんな関数がそもそも存在するだけでしょうか? わかりません。教えてください。

このQ&Aのポイント
  • ELECOM PKB-DE10のキーボードが切れてきたため、新しいものに変えたいと考えています。しかし、購入方法がわからないので教えてください。
  • ELECOM PKB-DE10を使用していますが、キーボードが故障してきています。新しいキーボードを購入したいのですが、どのように購入すれば良いでしょうか?
  • ELECOM PKB-DE10のキーボードを使っていて、最近調子が悪くなってきました。新しいキーボードを購入したいのですが、どこで購入できるのか教えてください。
回答を見る