我需要散列一个数字(大约 22 位数字),结果长度必须小于 12 个字符。它可以是数字或字符的混合,并且必须是唯一的。(输入的数字也将是唯一的)。
例如,如果输入的数字是 000000000000000000001,则结果应该类似于 2s5As5A62s。
我查看了典型值,如 MD5、SHA-1 等,但它们给出的结果很长。
您的问题的问题是输入大于输出并且是唯一的。如果你也期待一个独特的输出,它就不会发生。这背后的原因是,如果您有一个 22 位数字的输入空间(10^22 种可能性)和一个长度为 11 位(16^11 种可能性)的十六进制数字的输出空间,那么您最终得到的输入可能性比输出可能性。
下图显示,您需要一个 19 位十六进制数字的输出空间和一个完美的一对一函数,否则您将经常发生冲突(超过 50% 的时间)。我认为这是您不想要的,但您没有指定。
由于无法完成您想要的操作,因此我建议您重新考虑您的设计或使用校验和,例如循环冗余校验(CRC)。CRC-64 将产生一个 64 位的输出,当使用任何base64算法编码时,会给你一些你想要的东西。这不提供像 SHA-1 那样的加密强度,因此它永远不应该用于与信息安全相关的任何事情。
但是,如果您能够更改您的标准以允许长哈希输出,那么我强烈建议您查看SHA-512,因为它将提供高质量的输出,并且重复的可能性极低。我的意思是,在算法的历史中,还没有两个输入等于相同的哈希值。
如果这两个建议仍然不适合您,那么您的最后一个选择可能只是在输入数据上仅使用 base64。它将基本上以最佳方式利用标准英文字母表来表示您的数据,从而尽可能减少字符数,同时保留输入数据的完整表示。这不是哈希函数,而只是一种编码二进制数据的方法。
为什么不采用 MD5 或 SHA-N 然后重构为 BASE64(或 base-whatever)并只采用 12 个字符?注意:在所有情况下,哈希永远不会是唯一的(但可以提供低冲突概率)
如果必须是唯一的,则不能使用哈希。
您需要大约 74 位来存储这样的数字。如果将其转换为 base-64,它将大约为 12 个字符。
您能否详细说明您对哈希的要求是什么?你需要确保结果是多样化的吗?(即不是 1 = a,2 = b)
只是大声思考,稍微横向思考一下,但你能不能对你的号码应用游程编码的原则,把它当作你想要压缩的数据。然后,您可以使用压缩版本的 base64 版本。