セキュリティが問題にならない場合、あなたが説明しているのは私の意見ではハッシュ関数ではありません. ハッシュ関数は一方向関数です。つまり、ハッシュの計算は簡単ですが、元に戻すのは「難しい」か、理想的には不可能です。
代わりに、要件は単射関数を記述します ドメイン X 内の x1、x2 を考えると、次が成り立ちます。
For all x1, x2 element of X, x1 != x2 => f(x1) != f(x2)
f(x) = x はそのような関数ですが、f(x) = x² はそうではありません。簡単に言えば、入力が異なる場合は異なる結果が必要であり、入力が同じ場合にのみ同じ結果が必要です。これは安全なハッシュにも当てはまりますが、f(x) しか与えられていない場合、x を (簡単に) 見つけることができないという特性など、一方向の特性を追加で提供します。私が理解している限り、これらのセキュリティ プロパティは必要ありません。
自明なことですが、このような String から Float への単射マッピングは、"String バイト" を "Float バイト" として単純に解釈することで得られます。つまり、バイトを別の方法で解釈します (C:
unsigned char *bytes = "...";
double d = (double)bytes;
)。しかし、これには欠点があります - 本当の問題は Float が最大の精度を持っていることですdouble
. )。そのため、ほとんどすべてのユースケースに十分なスペースがありません。最初に文字列を MD5 処理しても問題は解決しません。MD5 出力はすでに 16 バイトの長さです。
したがって、正確な要件によっては、これが実際の問題になる可能性があります。MD5 (またはその他のハッシュ) は、入力を可能な限りランダムにするために十分に混乱しますが、可能な値の範囲を 16 バイトから事実上 8 バイトに削減します。(注: ランダムな 16 バイト出力を 8 バイトで切り捨てることは、ランダム性を維持するという点で一般に「安全」と見なされます。楕円曲線暗号は同様のことを行います。しかし、私の知る限り、誰も実際にそれを証明することはできません。今までと逆)。したがって、制限された Float 範囲では衝突が発生する可能性がはるかに高くなります。誕生日のパラドックスにより、衝突を見つけるには sqrt (有限範囲内の値の数) の試行が必要です。MD5 の場合、これは 2^64 ですが、あなたのスキームでは 2^32 しかありません。それでも、衝突が発生する可能性は非常に低いです。これ' 雷に打たれながら宝くじに当選するようなものだろう。この最小限の可能性で生活できる場合は、それを選択してください。
def string_to_float(str)
Digest::MD5.new.digest(str).unpack('D')
end
一意性が絶対的な優先事項である場合は、浮動小数点から整数に移行することをお勧めします。Ruby には、値の内部制約によって制限されない大きな整数のサポートが組み込まれていlong
ます (これが Fixnum の要約です)。したがって、任意のハッシュ出力は大きな整数として表すことができます。