入力文字列を指定すると、文字列の長さは 30 以下になり、出力は一意の ID 番号になります。Java でこれを行う方法はありますか?同じ文字列は常に同じ ID を生成しますが、異なる文字列は同じ ID を生成できません。Java HashCode() はこれを行うことができますか?
ありがとう
入力文字列を指定すると、文字列の長さは 30 以下になり、出力は一意の ID 番号になります。Java でこれを行う方法はありますか?同じ文字列は常に同じ ID を生成しますが、異なる文字列は同じ ID を生成できません。Java HashCode() はこれを行うことができますか?
ありがとう
要件を満たすために
同じ文字列は常に同じ ID を生成しますが、異なる文字列は同じ ID を生成できません
かなりの数が得られます。関数が単射である必要があるため、可能な s の数と同じ数が必要ですString
。これは、この場合は $255^30$ のようなものです (任意の Unicode 文字を許可する場合は $65536^30$ のようなものです)。したがってBigInteger
、そのために s が必要になり、確かに使用しますint
(単純にString
、 の数字よりも 30 までの長さの s の方が多くありますint
)。たとえばnew BigInteger(theString.getBytes(""))
、要件を満たします。
を使用するhashCode
と、単射性が失われますが、ほとんどの場合、2 つString
の s が同じになる可能性hashCode
は非常に低くなります (実際には、この可能性を低くすることがハッシュの目的です)。衝突の数が一様に小さいことをさらに確認したい場合は、暗号化ハッシュ関数を使用できますが、それでもマッピングは単射ではありません。
おそらく、要件の理由を説明すると、最適なソリューションを見つけるのに役立ちます。
Java ハッシュコードは一意であるとは限りません。UUID を調べる必要があります。
public static UUID nameUUIDFromBytes(byte[] name)
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html
少しばかげているかもしれませんが、すべての文字をASCII番号に変換するのはどうですか?
衝突がないことを本当に確認する必要がある場合、得られる数値は非常に大きくなり、どのプリミティブ数値型よりも確実に大きくなります。私のアドバイスは、ほぼ確実に十分な SHA-1 ハッシュを使用することです (Git バージョン管理システムは、これらのハッシュ値の一意性に依存しています。あなたの要件は、彼らの要件よりも本当に厳しいですか?)
一意性を保証したい場合は、各文字の ASCII (または入力によっては Unicode) の数値を取得し、すべての値が同じ長さになるようにゼロを埋め込む方法があると思います。次に、それらをすべて連結して 1 つの大きな数にします。前述のように、これを long 値に適合させる方法はないため、BigInteger クラスを使用する必要があります。「12 + 34」や「123 + 4」などの衝突を避けるために、パディングが必要になります。
有効な文字列のセットを決定論的な方法で制限できない限り、唯一のオプションは、文字列全体を ID として解釈することです。非常に大きな ID を取得するので、BigInteger クラスを使用して ID を表す必要があります。
異なる長さの文字列について心配する必要がないように、文字を逆の順序で変換します。