【问题标题】:Convert string to hash and then reform the string later将字符串转换为散列,然后再重新转换字符串
【发布时间】:2010-10-29 09:16:16
【问题描述】:

我需要对一些字符串进行哈希处理,以便将它们传递到一些库中,这可以直接使用 String.hashCode 调用。

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

【问题讨论】:

  • 您可以为此使用加密或编码/解码(可能是base64)。

标签: java hash


【解决方案1】:

hashCode() 通常不会是 bijection,因为它通常不会是 injective 映射。

hashCode() 的范围为 ints。只有 2^32 个不同的 int 值,因此对于可能有超过 2^32 个不同值的任何对象(例如,考虑 Long),您可以保证(pigeonhole principle 至少两个不同的对象将具有相同的哈希码。

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。

【讨论】:

    【解决方案2】:

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

    所以不,这是不可能的。

    【讨论】:

    • 此外,这首先是哈希的意义。
    • @JoeriHendrickx,这取决于应用程序。事实上,perfect hash function 没有任何冲突。
    • @aioobe 肯定,但你不能有一个完美的 Java 字符串散列。可能的字符串多于可能的 long。
    • 是的,但散列函数的并不总是单向的,或者它应该能够产生冲突。如果是这样,那么Integer.hashCode 将被破坏。
    【解决方案3】:

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

    您可以使用base64 encoder scheme 对数据进行编码,在任何您想使用的地方使用它,然后将其解码为原始形式。

    【讨论】:

      【解决方案4】:

      这通常是不可能的。 hashCode 就是人们所说的 one-way-function

      此外,字符串比整数多,因此存在从整数到字符串的一对多映射。例如,字符串"0-42L""0-43-" 具有相同的哈希码。 (Demonstration on 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 (commons.apache.org/collections/api-3.1/org/apache/commons/…) 对这种方法进行补充。请注意哈希冲突.. :)
      • 最好使用 Map>。这样,您可以将哈希映射到相应的字符串,因为它们可以是多个。
      • 这很好。但他仍然需要在与某个哈希码对应的字符串List&lt;String&gt;中进行猜测。
      猜你喜欢
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      • 1970-01-01
      • 2019-10-10
      • 2011-12-18
      • 2012-01-08
      相关资源
      最近更新 更多