4

我想自动生成 Java 的 serialVersionUID(很长,或 64 位)。要序列化的对象的区别是由大约 20 个整数决定的,但并不总是 20 个整数。我打算将整数转换为逗号分隔的数字字符串,并通过 SHA-256 哈希函数运行它。

由于 SHA-256 的长度为 32 字节(256 位),并且我需要它来适应 serialVersionUID(64 位),我如何将其转换为 64 位值并最大限度地减少良好哈希特性的损失?

4

5 回答 5

5

只需切断多余的部分。没有必要使事情复杂化。如果有一种更好的方法来获取第一个(或任何其他)64 位,那么哈希首先会被破坏。

于 2012-10-19T13:13:55.820 回答
3

首先,你不可能在正常意义上压缩一个好的散列。压缩是关于减少冗余的可逆编码。在一个好的散列中不应该有冗余来减少,因此压缩将是无效的。

由于 SHA-256 的长度为 32 字节(256 位),并且我需要它来适应 serialVersionUID(64 位),我如何将其转换为 64 位值并最大限度地减少良好哈希特性的损失?

那么这些好的特性是什么?好的散列的主要特征是反转它是不切实际的。即,计算出导致散列的可能输入是不切实际的。一个相关的特征是,给定一个产生给定哈希的已知输入,产生另一个给出相同哈希的输入(即冲突)是不切实际的。

现在,当您从 256 位散列到 64 位散列时,您可以更轻松地反转散列或产生散列冲突……通过蛮力。基本上,64 位散列意味着2^64任何随机输入都有一个给定散列的机会。这个概率足够大,以至于一些拥有足够核心的“坏人”有足够大的成功机会(在合理的时间内)使蛮力成为一个合理的选择。

但这真的重要吗?有人会通过创建一个冲突的 serialVersion 字符串来实现什么?这些字符串不是秘密,它们不会告诉你任何关于对象 API 的明确信息......

底线是,如果这些简化的散列被用作 serialVersion 字符串被设计使用,那么(例如)仅使用 SHA-256 散列的前 64 位不会有任何问题。不需要 XOR 或校验和或进行任何其他更复杂的转换。

于 2012-10-19T13:58:31.067 回答
1

您可以计算 SHA-256 摘要的循环冗余校验 (CRC)。

于 2012-10-19T13:16:04.207 回答
0

我会说要么使用 64 位校验和,或者如果你想坚持使用 SHA,那么对 64 位块进行异或。

于 2012-10-19T13:11:13.200 回答
0

用ripemd-160 对其进行哈希处理。

例如,

4727c1278432c388eea822904f008468c02fd543fc347391d1f2b9918ec9b5b9

变成

069e298ee9d1b14e7774434624703c0be1a47ee1

即 66 个字符,减少到 40 个。

于 2019-01-29T13:30:18.100 回答