将字符串转换为哈希值,然后稍后重新构造字符串。

12

我需要对一些字符串进行哈希处理,以便将它们传递给某些库。使用String.hashCode调用可以很容易地完成此操作。

但是,一旦所有内容被处理完毕,我想将从hashCode生成的整数转换回原来的字符串值。显然,我可以在其他地方跟踪字符串和哈希代码值并在那里执行转换,但我想知道Java中是否有任何自动执行此操作的东西。


2
你可以使用加密或编码/解码(可能是base64)来实现这个。 - jerjer
4个回答

29

我认为你误解了哈希的概念。哈希是一个单向函数。更糟糕的是,两个字符串可能会生成相同的哈希值。

所以,不,这是不可能的。


1
此外,这也是哈希的首要目的。 - Joeri Hendrickx
@JoeriHendrickx,这取决于应用程序。事实上,_完美_哈希函数没有任何冲突。 - aioobe
@aioobe 当然可以,但是你无法为Java字符串创建完美的哈希。可能的字符串比可能的长整型更多。 - Joeri Hendrickx
是的,但哈希函数并不总是要具备单向性,或者说它应该能够生成冲突。如果是这样的话,那么Integer.hashCode就会出问题。 - aioobe

9

hashCode()通常不会是一个双射,因为它通常不会是一个单射映射。

hashCode()的范围是int。只有2^32个不同的int值,所以对于任何对象,如果有超过2^32个不同的对象(例如,考虑Long),你可以保证(通过鸽巢原理)至少有两个不同的对象将具有相同的哈希码。

hashCode()给你的唯一保证是,如果a.equals(b),那么a.hashCode() == b.hashCode()。每个对象具有相同的哈希码都与此一致。

您可以使用hashCode()在某些非常有限的情况下唯一标识对象:必须有一个特定的类,其中没有超过2^32个可能不同的实例(即,最多有2^32个对象属于您的类,它们成对这样!a.equals(b))。在这种情况下,只要确保每当!a.equals(b)ab都是您的类的对象时,a.hashCode()!= b.hashCode(),则会在对象和哈希码之间具有双射(等价类)。 (例如,可以为Integer类执行此操作。)

但是,除非您处于这种非常特殊的情况,否则应通过其他方式创建唯一ID。


8
一般情况下是不可能的。hashCode就是所谓的单向函数
此外,字符串比整数更多,因此整数到字符串之间存在一对多映射。例如,字符串"0-42L""0-43-"具有相同的哈希值。(ideone.com上的演示。
但是,您可以(作为估计)将传递到API中的字符串存储起来并记住它们的哈希码,如下所示:
import java.util.*;

public class Main {
    public static void main(String[] args) {

        // Keep track of the corresponding strings
        Map<Integer, String> hashedStrings = new HashMap<Integer, String>();

        String str1 = "hello";
        String str2 = "world";

        // Compute hash-code and remember which string that gave rise to it.
        int hc = str1.hashCode();
        hashedStrings.put(hc, str1);

        apiMethod(hc);

        // Get back the string that corresponded to the hc hash code.
        String str = hashedStrings.get(hc);
    }
}

这种方法的一个补充是使用BiDiMap(http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html),如果您需要进行反向查找。只需注意哈希冲突即可.. :) - posdef
最好使用Map<Integer,List<String>>。这样,您可以将哈希映射到相应的字符串,因为可能会有多个字符串。 - Carra
这是一个很好的观点。但他仍然需要在List<String>字符串中猜测哪些对应于特定的哈希码。 - aioobe

2

无法将.hashcode()输出转换为原始形式。这是一个单向过程。

您可以使用base64编码方案对数据进行编码,然后在需要时使用它,最后将其解码回原始形式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接