【问题标题】:Java recreate string from hashcodeJava从哈希码重新创建字符串
【发布时间】:2011-06-13 18:27:47
【问题描述】:

有什么方法可以在 java 中使用字符串的哈希码并重新创建该字符串?

例如像这样:

String myNewstring = StringUtils.createFromHashCode("Hello World".hashCode());
if (!myNewstring.equals("Hello World"))
    System.out.println("Hmm, something went wrong: " + myNewstring);

我这么说是因为我必须把一个字符串变成一个整数值,然后从那个整数值重构那个字符串。

【问题讨论】:

  • 你为什么要放在首位?
  • @Srinivas 请阅读整个问题。
  • @adarshr 和长答案?我真的不在乎代码有多大,我只需要知道如何做到这一点。
  • 长答案与短答案相同——只是更多的单词。
  • ...您还没有真正回答这个问题。为什么需要将字符串转换为整数值并返回?你打算如何处理整数值?

标签: java string hashcode construct


【解决方案1】:

这是不可能的。 String 的哈希码是有损的;许多字符串值将产生相同的哈希码。一个整数有 32 位位置,每个位置有两个值。甚至没有办法将 32 个字符的字符串(例如)(每个字符都有很多可能性)映射到 32 位而不发生冲突。他们就是不适合。

如果你想使用任意精度的算术(比如,BigInteger),那么你可以把每个字符当作一个整数,然后将它们连接在一起。瞧。

【讨论】:

  • 那么我可以使用另一种方法吗?某种类型的编码?
  • @Richard,Base 10 是您使用的编码。
  • @Richard 你需要的是加密/解密。
  • @Marcelo,对使用什么加密有什么建议吗?
  • 我无法相信这种使用加密的想法是多么愚蠢。到底如何才能从限制为 32 位的密文中恢复可能无限长的消息?
【解决方案2】:

没有。多个字符串可以具有相同的哈希码。理论上,您可以创建所有具有该哈希码的字符串,但它几乎是无限的。

【讨论】:

  • 那么我可以使用另一种方法吗?某种类型的编码?
  • 或者你可以压缩它。使用 java.util.zip 压缩字符串
  • 加密和压缩都不能解决问题中提到的问题。这些并不是用来解决本质上涉及数据丢失问题的魔术术语。
【解决方案3】:

恐怕不可能。想想看,哈希码是一个长值,即 8 个字节。一个字符串可能比这个少,但也可能更长,你不能把一个更长的字符串压缩成 8 个字节而不丢失一些东西。

如果我没记错的话,Java 哈希码算法每 8 个字节求和一次,所以你会丢失 8 个字节中的 7 个。如果您的字符串都很短,那么您可以将它们编码为 int 或 long 而不会丢失任何内容。

【讨论】:

    【解决方案4】:

    假设字符串仅由字母、数字和标点组成,因此可能有大约 70 个字符。

    log_70{2^32} = 5.22...

    这意味着对于任何给定的整数,您都会找到一个 5 或 6 个字符的字符串,并以此作为其哈希码。所以,检索"Hello World":不可能;但如果幸运的话,"Hello" 可能会起作用。

    【讨论】:

    • 显然,除了极少数例外,所有英文单词在 Java 的 hashCode 操作下都映射到一个不同的数字。所以如果你有单个单词的哈希,你可以通过字典检查哈希码,并且很有可能恢复原始单词。
    • 确实是一个非常有趣的发现。唉,这个问题意味着要存储任意字符串,或者至少是多个单词的序列。
    【解决方案5】:

    例如,“1019744689”和“123926772”的哈希码均为 -1727003481。这证明对于任何整数,您都可能得到不同的结果(即reversehashcode(hashcode(string)) != string)。

    【讨论】:

      【解决方案6】:

      你可以这样做:

      char[] chars = "String here".toCharArray();
      int[] ints = new int[chars.length];
      for (int i = 0; i < chars.length; i++) {
          ints[i] = (int)chars[i];
      }
      

      然后:

      char[] chars = new char[ints.length]
      for (int i = 0; i < chars.length; i++) {
          chars[i] = (char)ints[i];
      }
      String final = new String(chars);
      

      我还没有实际测试过……这只是“概念”代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-05
        • 2010-11-15
        • 2019-04-01
        • 1970-01-01
        • 2012-08-23
        • 1970-01-01
        相关资源
        最近更新 更多