从Long id生成唯一哈希

时间:2013-07-29 09:52:31

标签: java algorithm hash

我需要从Long类型的ID值生成唯一哈希。我担心的是它不应该从两个不同的Long/long值全局生成相同的哈希值。

MD5哈希看起来很不错,但哈希字符串非常长。我只需要字符

0-9
a-z and A-Z

只有6个字符,如:j4qwO7

什么是最简单的解决方案?

6 个答案:

答案 0 :(得分:13)

无法满足您的要求。您有一个包含62个可能字符的字母表,并且有6个字符可用 - 这意味着该表单中有62个 6 可能的ID。

但是,有256个 8 可能的long值。通过pigeon-hole principle,不可能为每个long值赋予给定表单的不同ID。

答案 1 :(得分:1)

您不必使用十六进制表示法。使用函数中的实际哈希字节构建自己的哈希表示。您可以截断哈希输出以简化哈希表示,但这会使冲突更有可能。

修改

其他答案表明,根据可能的long值的数量,您提出的要求是不可能的,从理论上来说是正确的, 如果 您实际上需要整个范围。

如果您的ID从零开始自动递增, 62^6 = 56800235584值可能对您来说绰绰有余,具体取决于您的需求。

答案 2 :(得分:0)

你的问题没有意义。

  1. 'Unique hash'是一个矛盾。

  2. Java long的'unique hash'值必须长度为64位,就像long本身一样,当然最简单的哈希函数是{{1} }即f(x) = x,值本身。

  3. 可以是0-9,A-Z和a-z的6个字符只能产生long个不同的值,这是不够的。

答案 3 :(得分:0)

步骤1.切换到使用in而不是long,或允许更长的“哈希”。请参阅每个其他答案,以讨论为什么6个字符不足以处理多头。

步骤2.使用不使用填充的算法加密您的号码。就个人而言,我建议使用skip32编码。我没有承诺这对于安全性来说足够强大,但如果你的目标是“制作具有随机性的ID”,那么效果很好。

步骤3.将您的号码编码为base_62号码(与base_10相反,而不是与base64编码相对)。

答案 4 :(得分:0)

  1. 您可以使用长值iself与hash相同(用于索引/搜索)。

  2. 如果您需要混淆/隐藏长值,可以使用任何对称 64位块的加密算法,例如 - ECB模式下的DES或AES。

答案 5 :(得分:0)

更新

无需使用Hashids。基地36足够了。

long id = 12345;
String hash = Integer.toString(Math.abs((int)id), 36);

原始答案,Hashids:

您可能想要使用Hashids

long id = 12345;
Hashids hashids = new Hashids("this is my salt");
String hash = hashids.encrypt(id); // "ryBo"

"ryBo"将是唯一的,因为它可以转换回你的长。 Hashids只是转换,不会进一步散列。

long[] numbers = hashids.decrypt("ryBo");
// numbers[0] == 12345

如果你真的有一个64位的值,那么哈希字符串将会很长(大约16个字符,具体取决于字母表),但是如果你不打算拥有超过2 ^ 16个东西,那么你可以将64位哈希截断为32位(一个int)。

long id = 12345;
String hash = hashids.encrypt(Math.abs((int)id));