繁体   English   中英

从Long id生成唯一哈希

[英]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值可能对您来说足够了。

你的问题没有意义。

  1. “独特的哈希”是一个矛盾。

  2. Java long的“唯一散列”值必须长度为64位,就像long本身一样,当然最简单的散列函数是f(x) = x,long值本身。

  3. 可以是0-9,AZ和az的6个字符只能产生62^6 = 56800235584不同的值,这是不够的。

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

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

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

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

  2. 如果需要混淆/隐藏长值,可以使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM