[英]Generate Unique hash from Long id
我需要从Long
类型的ID值生成唯一的哈希。 我担心的是它不应该从两个不同的Long/long
值全局生成相同的哈希值。
MD5哈希看起来很不错,但哈希字符串很长。 我只需要角色
0-9
a-z and A-Z
只有6个字符,如:j4qwO7
什么是最简单的解决方案?
您的要求无法满足。 您有一个包含62个可能字符的字母表,并且有6个字符可用 - 这意味着该表单有62个6个可能的ID。
不过,也有256个8可能的long
价值。 根据鸽子洞的原则 ,不可能给每个long
值赋予给定形式的不同ID。
您不必使用十六进制表示。 使用函数中的实际哈希字节构建自己的哈希表示。 您可以截断哈希输出以简化哈希表示,但这会使冲突更可能发生。
编辑:
另一个答案表明, 如果您确实需要整个范围, 那么基于可能的long
值的数量,您所要求的是不可能的,从根本上说是真实的。
如果您的ID从零开始自动递增,则根据您的需要, 只有 62^6 = 56800235584
值可能对您来说足够了。
你的问题没有意义。
“独特的哈希”是一个矛盾。
Java long
的“唯一散列”值必须长度为64位,就像long
本身一样,当然最简单的散列函数是f(x) = x,
即long
值本身。
可以是0-9,AZ和az的6个字符只能产生62^6 = 56800235584
不同的值,这是不够的。
步骤1.切换到使用in而不是long,或允许更长的“哈希”。 请参阅每个其他答案,以讨论为什么6个字符不足以处理longs。
步骤2.使用不使用填充的算法加密您的号码。 就个人而言,我建议使用skip32编码。 我没有承诺这对于安全性来说足够强大,但如果你的目标是“制作具有随机性的ID”,那么效果很好。
步骤3.将您的号码编码为base_62号码(与base_10相反,而不是与base64编码相对)。
您可以使用长值iself与hash相同(用于索引/搜索目的)。
如果需要混淆/隐藏长值,可以使用64位块的任何对称加密算法,例如 - ECB模式下的DES或AES。
更新 :
无需使用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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.