ハッシュ関数を利用して情報を要約する方法とその意義について

このQ&Aのポイント
  • あらゆる情報をハッシュで一定量に揃えることができれば、情報の特定性と意味を切り離す方向で考えられる。
  • 文字数制限があるプログラムの関数名はハッシュ値で決めることができ、専用ビューワーやエディターで閲覧編集する必要がある。
  • Webサービスで既に取られたID名はハッシュを利用して他のIDと区別し、対応表をネットに置く方法もある。
回答を見る
  • ベストアンサー

あらゆる種類の情報をハッシュで一定量に揃えれるなら

0バイトの情報(情報が無いという情報)でもデータセンター1棟丸ごとの情報でも、もし仮にハッシュ関数を通すことができれば、一定のビット数で要約ができるのなら(他の情報と区別がつけられるのなら)、情報の表す意味と、その情報の特定性は、切り離す方向で考えたほうがいいのでしょうか。 例1 プログラムの作成時、関数名を決めたいが文字数制限があってうまく決められない→ 自分で充分に満足するような関数名をまずメモ帳にでも書いてみて、プログラムソース上はそのハッシュ値で関数名を決めてしまう。(当然、読みづらいソースになるので、HTMLのブラウザのような専用ビューワやエディターで閲覧編集する) 例2 あるWebサービスである名前でIDを取りたいが既に他人に取られていて自分のものとして使えない→諦めてハッシュをIDとする(それでも取られていたら変更回数として0でも末尾につけてまたハッシュする) そのWebサービスで取りたかったID名との対応表みたいのもまたネットに置いておく(オンラインブックマークにコメント記入するなど)

質問者が選んだベストアンサー

  • ベストアンサー
  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

> 例1 衝突したときに備えて、テーブルが必要ですが、 それならハッシュである必要がなく、連番などでもかまわない。 (ハッシュは衝突する可能性があるので、むしろ連番とかの方がいい。) ※こういう関数名の短縮がもし必要なら、手動ではなくツールなどを通して自動でするべきでしょうね。 > 例2 ハッシュ関数への入力が同じなら出力も当然同じなので、 重複IDへの対策としては何の解決にもなっていないです。 また、対応表を作るならハッシュである必要がない。 (この対応表って、希望ID→実IDが1対多の関係になるので希望IDだけ覚えていたのでは 自分の実IDが分からなくなります。結局実IDを覚える必要あり。) 普通に希望のIDの末尾に数字とかつければよいところを、面倒にしているだけだと思います。

kasoupctte
質問者

お礼

くだらない妄想につきあっていただきありがとうございました(^o^)

kasoupctte
質問者

補足

SHA256のような衝突未発見のハッシュ関数を前提にしてしまっていました。 もし衝突発見されたらSHA512とかに速やかに移行できる仕組みも作っておくとか(運用によっては無理かな?) でも昔都市銀行が統合したときとか結構な混乱があってもどうにかなったし 社会的に許容できるような制度も作っておけばなんとかなるのでは・・・ ハッシュ関数移行のため臨時休業致しますとか・・全部の機関が閉まるのでなく時差を設ければ・・ 例2についてはひとつのハッシュ値からIDでもパスでも全て展開するというのがしたかったからです

関連するQ&A

  • なんでハッシュ関数はユーザーに直接活用されない?

    何故でしょう? 一番根本のハッシュというか種パスワードみたいのはそりゃ秘匿に充分気を使うから大変かもですが しかしひとつだけに絞れるわけだし 電卓みたいなデバイスを考えてもいいし せっかくインターネットという真の意味でグローバルな(アメリカ一極化という意味でなく)ネットワークがあるのに URLのところにハッシュ値を入れれば即対応する内容が表示されればそれでいいのでは? 認証させたけりゃIDパスワードの2要素で充分だし そのIDパス自体もハッシュで決めればいいし 上流でハッシュ変更したら自動的にIDでもパスでも順番に変更が反映されていくような プロトコルでも開発して全Webサービスが実装すればいいし ハッシュ関数なんてすごいものがありながら何で活用されていないのでしょうか?? 単純に不思議です 一昔前なら誰かがチラとこういうアイデア出せば飛びついて無理やりにでも実装したのに 少し時期がすぎると誰も見向きもしないし、で今熱いのはアンドロイドとかみたいですが 相変わらず情報セキュリティみたいのはダメダメだし もうあきらめてハッシュ電卓にしたらどうですか???

  • ハッシュ関数

    ハッシュ関数について悩んでいます. ハッシュ関数の例として以下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を掛けるのかを理解できません. どなたかわかりやすくご教授いただけたら幸いです.

  • ハッシュ法(オープンアドレス)線形探査法と再ハッシュ法

    1から10000までの数字がランダム(重複なし)にはいっているファイルから任意に10個の数字を選びハッシュ法(オープンアドレス)の線形探査法と再ハッシュ法を使って探すプログラムを作りたいのですがまったく手がでません。さらに探査回数と実行時間も出力しなければなりませんが、こちらはなんとかできます。ハッシュ法というのが初めてで困っています。どなたか教えてください。お願いします。 ちなみにファイル名は次のようにmain関数中に絶対パスで記述します。 char infile[20] = "/integer.dat"; int in[10]={20,168739,701,52774,44476,185,994737,124623,645300,999901};

  • proxyはどこを見てキャッシュに情報があると判断しているのか教えてください

    環境:クライアントA,B⇔Proxy⇔webサーバ 前提:クライアントAはWebサーバへアクセスしa.htmlをgetしている。 クライアントBがWebサーバへアクセスしa.htmlをgetする際、 間に入っているProxyサーバ内に「a.html」がキャッシュされている為 ProxyからクライアントBにa.htmlファイルが渡されます。 その際のProxy内のアクションについて質問です。 ProxyサーバはクライアントBからどの情報基にa.htmlが自分の キャッシュ内に存在すると判断しているのでしょうか? 自分の考えでは  ファイル名だけだとa.htmlの内容が変更された場合、  変更前の情報を渡してしまうと思っており、クライアントAのアクセスから得た  a.htmlファイルにハッシュ関数を使用して任意のIDを付けた上でキャッシュに格納し  クライアントBからa.htmlのget要求を受けた場合、ハッシュ関数を使用してハッシュ値  を求め、キャッシュ内のIDを見て判断しているではと考えております。 以上です。 よろしくお願いします。

  • ハッシュのキー追加について

    とある既存プログラムに機能追加したいのですが上手くいきません。 ハッシュだとは思うのですが、%だったり$だったりしてよくわからなくなってしまいました。 どこがおかしいか教えていただけないでしょうか。 <概要> もともとあった(1)と(3)の処理の間に、(2)を行う <ソース> (1)DBから1レコードを取得する $sql = "select * from tenpo where id=5;"; $sth = $dbh->prepare($sql); $sth->execute(); $shop = $sth->fetchrow_hashref(); (2)別TABLEから値を取得し、(1)に追加する $sql = "select todoufuken from area where id=5;"; $sth = $dbh->prepare($sql); $sth->execute(); @todoufuken= $sth->fetchrow_array; $shop{place} = $todoufuken[0]; (3)$shopの情報をサブルーチンに渡す ソース略

    • ベストアンサー
    • Perl
  • ハッシュ(オープンアドレス法) C言語の課題

    努力はしてみたのですが、C言語の課題ができません。教えていただけないでしょうか。 問:名前と年齢を入力し、名前をキーとしてハッシュ(オープンアドレス法)に登録する。'-'が入力されると登録を終了し、次に入力された名前をハッシュ法で検索し、あればその人のデータをハッシュから削除する、その後、ハッシュ表の内容を出力するプログラムを作成せよ。ただしハッシュ表の大きさは5とする。 例 koizumi  入力 1     入力 fukuda  入力 2  入力 aso 入力 3     入力 -     入力 koizumi  入力 fukuda(2) 出力 aso(3) 出力 ハッシュ関数は int hash(char *name) { int ret=0; while (*name)ret += *name++; return ret%5; } 再ハッシュ関数は int rehash(int h) { return (h+1)%5; } を使おうと考えています。 内容を理解できないと困るので簡単なプログラムをお願いします。 よろしくお願いします。

  • 数値・文字列を決まった範囲の数値に変換・割り当てる(ハッシュする?)方

    数値・文字列を決まった範囲の数値に変換・割り当てる(ハッシュする?)方法について ハッシュ関数を使えば、ある文字列・数値を何らかの法則で暗号のように変換できることは分かったのですが、その変換される結果の範囲を決まった数値として指定することは可能なのでしょうか。 例えば『文字列を「1~95」の数値のどれかに割り当てたい』という感じです。 ランダムでなく、何度やっても同じ結果にしたいのです。 また、範囲は例では「1~95」としていますが、「1~230」「1~500」など自由に変更したいと思っています。 ※以前質問した占いに関連するものでして、結果の数が定まっていないため、 結果の数に応じて、元となるデータから占い結果に割り当てるということをやりたいと思っています。 ご教示いただけますようお願いします。

    • ベストアンサー
    • PHP
  • c言語 ハッシュ表

    下のハッシュ表のプログラムについて質問です.関数enterを二回呼び出して,valueの値を変更して表示させても値が更新されません.値が更新せれるにはどうすればよいのでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASH_SIZE 997 /* ハッシュ表の内部配列のサイズ */ #define HASH_RADIX 97 /* ハッシュ関数用の基数 */ /* ハッシュ表内の連結リストに含まれるノードの構造体 */ struct hash_node { /* ハッシュ表内の連結リストのノード */ char *key; /* キー */ int value; /* キーに対応する値 */ int id; /* キーに付与された通し番号 */ struct hash_node *next; /* 次のノードへのポインタ */ }; typedef struct hash_node HashNode; typedef HashNode *HashNodePtr; /* ハッシュ表の構造体 */ struct hashtable { HashNodePtr *heads; /* 内部配列 */ int serial_id; /* 通し番号管理用の変数 */ int size; /* 内部配列のサイズ */ }; typedef struct hashtable HashTable; typedef HashTable *HashTablePtr; /* 文字列 s のハッシュ値を計算する */ unsigned int hash(char *s) { unsigned int v; v = 0; while (*s != '\0') { v = v * HASH_RADIX + *s; s++; } return v; } /* ハッシュ表を一つ生成し,そのポインタを返す */ HashTablePtr create_hashtable() { HashTablePtr t = NULL; int i; t = malloc(sizeof(HashTable)); t->serial_id = 0; t->size = HASH_SIZE; t->heads = malloc(sizeof(HashNodePtr) * t->size); /* 各連結リストの先頭要素へのポインタは必ず NULL に初期化する */ for (i = 0; i < t->size; i++) { t->heads[i] = NULL; } return t; } /* 指定したポインタ変数に NULL を代入して終わるためのマクロ */ #define delete_hashtable(t) \ (delete_hashtable0(t),t=NULL) /* 実質的な削除作業を行う関数(free 後の NULL 代入は省略)*/ void delete_hashtable0(HashTablePtr t) { HashNodePtr n = NULL, m = NULL; int i; /* 各連結リストの領域を解放 */ for (i = 0; i < t->size; i++) { n = t->heads[i]; while (n != NULL) { m = n; n = n->next; free(m); } } /* 最後に連結リストの先頭ポインタの領域を解放 */ free(t->heads); free(t); } /* ハッシュ表 t に登録されているキーと値のペアの数を返す */ int get_cardinality(HashTablePtr t) { return t->serial_id; } /* ハッシュ表 t にてキー key に対応する値を調べる */ int lookup(HashTablePtr t, char *key) { HashNodePtr n = NULL; int index; /* ハッシュ表の内部配列の添え字を計算 */ index = hash(key) % t->size; /* index 番目の連結リストを先頭から順に走査 */ n = t->heads[index]; while (n != NULL) { /* 引数で指定された key とハッシュ表内のキーが一致したら 直ちに対応する値を返す */ if (strcmp(key, n->key) == 0) return n->value; /* 走査を次に進める */ n = n->next; } /* ここではキーに対応する値は非負であると仮定し, 見つからなかったら -1 を返す */ return -1; } /* キー key と値 value のペアをハッシュ表 t に登録し,その通し番号を返す */ int enter(HashTablePtr t, char *key, int value) { HashNodePtr n = NULL, m = NULL; int index; index = hash(key) % t->size; /* 内部配列の添え字を計算 */ /* キーが既に存在しているかどうかチェック(lookup() と同じ処理)*/ n = t->heads[index]; while (n != NULL) { if (strcmp(key, n->key) == 0) return n->id; /* 通し番号を返す */ n = n->next; } /* 新しいノードを生成 */ m = malloc(sizeof(HashNode)); m->key = _strdup(key); m->id = t->serial_id; m->value = value; /* 連結リストの add_first() と同様にして連結リストに追加 */ m->next = t->heads[index]; t->heads[index] = m; t->serial_id++; /* 次の通し番号に更新 */ return m->id; /* 登録したキーと値のペアに付与された通し番号を返す */ } /* * ハッシュ表 t に登録されるキーの配列を返す *(この配列のサイズは get_cardinality() で取得可能) */ char **get_keys(HashTablePtr t) { char **keys = NULL; HashNodePtr n = NULL; int i; keys = malloc(sizeof(char *) * t->serial_id); /* 各連結リストを走査し,配列に詰め込む */ for (i = 0; i < t->size; i++) { n = t->heads[i]; while (n != NULL) { keys[n->id] = n->key; /* 通し番号を配列添え字に */ n = n->next; } } return keys; /* 後で free() する必要あり */ } void print_hashtable(HashTablePtr t) { printf("Taro => %d\n", lookup(t, "Taro")); } /* ハッシュ表の使用例 */ int main(void) { HashTablePtr t = NULL; t = create_hashtable(); enter(t, "Taro", 25); print_hashtable(t); enter(t, "Taro", 35); print_hashtable(t); delete_hashtable(t); }

  • ハッシュ変数の怪

    お世話になります。 ハッシュ変数の扱い方について教えて下さい。 <最終的にヤリタイコト> ブログのRSSを読み込み、そのブログ自体のタイトル(1つ)を表示するプログラムを作成したい。 その為に、以下の様なプログラムを作成しています。 ------------------------------------ # 頻繁にRSSを読みに行くのを避けるため、 一時的に$blogfileにRSSファイルを保存しています。 $blogfile="./save/blog.rss"; use XML::RSS; use LWP::Simple; # 保存しているRSSデータを解析 $rss = new XML::RSS; $rss->parsefile($blogfile); # サイト情報を取得 $bigtitle = $rss->{channel}; # そして、これにつづけて、 print $bigtitle->{title}; とすると、ブログ名がキチンと印刷されます。 しかし、この場ではブログ名を表示させたくはなく、一旦、スカラー変数に、このブログ名を代入しておき、後になってから、スカラー変数に代入されたブログ名をprint文で表示させたいのです。 この場合、例えば、 print $bigtitle->{title}; の代わりに $blogtitle=$bigtitle->{title}; とやっても、$blogtitleにブログ名は代入されません。 また、$blogtitleをprint文で表示させてみると、 HASH(0x8ddb5d4) と、いつかどこかで見たような表示になってしまいます。 ●ブログ名をスカラー変数に代入する方法をご教授、よろしくお願い致します。(または、上記の方法以外で、とてもカンタンにブログのRSS情報を元に、そのブログ自体のタイトルのみをスカラー変数に代入するperlプログラムがありましたら、教えて下さい) よろしくお願い致します。

    • ベストアンサー
    • Perl
  • なぜパスワードが分かる・・・。?

     ココや、ヤフーなどのフリーメールのサービスなどで、IDとパスワードが必要な場合ってあるかと思います。 もしパスワードを忘れたら、メールで折り返し連絡がくるかと思います。 そこで気になるのですが、普通パスワードって、パスワードをハッシュ関数か何かで暗号化したものを保存しておき、ユーザーが入力したパスワードをハッシュ関数か何かで暗号化して一致するか同かを調べるとどこかで聞いた気がします。 そうだとすればなぜパスワードが分かるのでしょうか?