1
$hash = sha1(rand().microtime());

$hashをデータベースに保存するつもりです。

文字列を何度も入力するとSha1()、同じハッシュが生成されます。しかしmicrotime()、マイクロ秒で現在のUnixタイムスタンプを返す入力をした場合-将来のすべての呼び出しに対して異なるハッシュが保証されますか(現在の時刻が増加するため)。ここでは、将来の呼び出しを、前の呼び出しから少なくとも1分後にこの関数に対して行われた呼び出しと想定していますか?

あなたは何と言うでしょう?

このハッシュがデータベーステーブルにすでに存在するかどうかを確認するだけで一意性を確認できることはわかっていますが、上記のように使用したときに一意性を想定できるかどうかを知りたいだけです。

4

5 に答える 5

3

一意性を保証できる、定義済みの有限長の文字列を計算するハッシュ関数は絶対にありません。このような有限長の文字列は、可能な出力の数が有限ですが、入力の数は無限です。ハッシュ関数が衝突に対処しなければならないことは、それほど複雑ではありません。

そうは言っても、ハッシュされた文字列のサイズが長いほど、衝突の可能性は低くなります。

GUID やuniqidなども使用できますが、同じ問題です: 衝突の可能性があります。非常に可能性は低いですが、可能です。

一意であることを保証するものが必要な場合は、 のようなものAUTO_INCREMENT、または他の種類の ID を使用して一意性を確保します。

複雑に見える(しかし実際にはそうではない)ものだけが必要な場合は、... まあ、なぜでしょうか? しかし、それに固執している場合は、一意の ID をハッシュに詰め込むようなことを試してみてください。たとえば、次のようになります。

$hash = $id . sha1(rand().microtime());

また:

$sha1 = sha1(rand().microtime());
$hash = substr($sha1,0,20). '-'.$id.'-'. substr($sha1,21);
于 2012-08-06T09:46:59.277 に答える
2

一意性を保証できますか? いいえ。SHA1 は 160 ビットのハッシュを生成します。2^160から取得できる値は、可能な数を超えていますmicrotime。したがって、同じハッシュを生成する複数の値が存在します。ハッシュ値はすべての意図と目的に対してランダムに分散されるため、比較的短い時間間隔でも衝突が発生する可能性があります。

実際に一意性を仮定できますか? まぁ、保証は無いのであくまで確率論です。最小間隔を強制することは役に立ちません。ハッシュ衝突の確率は、2 つの観測間で同じです。でも確率はかなり低いので大丈夫です。それを手に入れたら世界が終わるのか、それとも少し不便を感じるだけなのかによって異なります... ;)

于 2012-08-06T09:36:52.193 に答える
2

uniqid()を使用して、独自に作成する必要はありません

于 2012-08-06T09:37:57.123 に答える
1

UUID を使用できます (このページのコメントから示されているように: http://php.net/manual/en/function.uniqid.php )。ただし、上記は UUID ではないため、そのまま挿入することはできません個性的。

紛争の可能性は 10 億分の 1 であると言えます。これは、取り出してrand()(これは実際に発生した何かに匹敵する可能性を実際に高める可能性があるためtime+rand)、時間のみで作業する場合に軽減できますが、実際にはすべてアクセスに依存します。MongoId時間に基づいて十分なアクセスがあるシャードの競合が発生する可能性があり、実際に...

于 2012-08-06T09:39:34.983 に答える