破解哈希算法

rmc*_*cmk 0 java algorithm cryptography

我试图破解Java中的哈希算法:

    public static int encode(String file) {
            int hash = 0;
            file = file.toUpperCase();

            for(int i = 0; i < file.length(); i++) {
                    hash = (hash * 61 + file.charAt(i)) - 32;
            }
            return hash;
    }
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

public static String decode(int hash) {
            long realHash = (hash < 0 ? Integer.MAX_VALUE + Math.abs(hash) : hash);
            ByteBuffer buffer = ByteBuffer.allocate(50);

            while (realHash > 0) {
                    buffer.put((byte) ((realHash % 61) + 32));
                    realHash = (realHash - 32) / 61;
            }
            buffer.flip();
            return new String(buffer.array()).trim();
    }
Run Code Online (Sandbox Code Playgroud)

我的解决方案似乎有严重的数据丢失,我认为由于整数溢出,我不能完全取消长文本数据.有什么建议?

Chr*_*nus 8

这不是整数溢出问题.这就像驾驶熔岩,让你的汽车爆炸,并断定你没有买到合适的汽油.

真正的问题是你不能"破解"哈希算法.有一个重要原因:

信息论

信息理论中有一个称为香农熵的术语.(公平警告:该文章不容易通过.)快速版本是编码任何给定的信息块所需的最小位数.

该站点具有计算器,该计算器声称确定对给定文本进行无损编码所需的熵量(即,最小位数).我提供了这一块手工填充文字:

Meggings牧草苦豆腐,Wes Anderson食品卡车工艺啤酒iPhone.单一来源的咖啡情景独角鲸,mumblecore mlkshk牛仔短裤chia信托基金艺术派对你可能还没有听说过他们的苦涩.宝丽来工艺啤酒Intelligentsia,乙烯基Marfa Brooklyn umami.

假设int您的系统是32位,您只有32位空间来编码任何给定文件.但是上面的那个块 - 与我可能使用的相比,如战争与和平或美国法典 - 并不需要太长时间,如果你想要重建文本的任何希望,至少需要1472位进行编码.

(Commentor templatetypedef指向Kolmogorov复杂性(对该概念的另一个很好的解释),这是一种更好的方式来表示字符串的信息内容和破解哈希的无用.)

因此,从理论上讲信息(并留下作弊,如预先填写的压缩字典),就不可能从32位int中重构那些少数(简单的手工制作的本地源代码)句子.不幸的是,这是宇宙的基本定律.不会发生.

实例,来自代码

另一个评论家提到了Pigeonhole原则 - 一个简单的想法,如果你有N个插槽(在这种情况下是2 ^ 32),你不能在它们中放置超过N个东西而不在同一个插槽中放入两个或更多东西.

我们来看看你的哈希函数:

public static int encode(String file) {
        int hash = 0;
        file = file.toUpperCase();

        for(int i = 0; i < file.length(); i++) {
                hash = (hash * 61 + file.charAt(i)) - 32;
        }
        return hash;
}
Run Code Online (Sandbox Code Playgroud)

具体来说,这一行:

file = file.toUpperCase();
Run Code Online (Sandbox Code Playgroud)

我想哈希两个文件:

mary had a little lamb

Mary Had A Little Lamb
Run Code Online (Sandbox Code Playgroud)

他们的哈希值是多少?想一想.

(旁注:即使说了这么多,你也会溢出.:) 模块化算术是你的朋友,如果你想做那样的事情.)

  • Kolmogorov复杂性在这里可能更容易,因为它讨论了用计算机程序压缩字符串. (3认同)
  • 我认为重要的是要添加,虽然你可以用32表示1472位,但还有许多其他1472位信息块将被压缩成相同的32位.区分它们是不可能的,因此在"破解"哈希之后你能想到的最好的方法是找出给定密钥属于哪种病理数据集. (2认同)
  • 我可能刚刚提到了[鸽子原理](http://en.wikipedia.org/wiki/Pigeonhole_principle) - 这是一个简单易懂的原则,它提供了足够的证据证明不可能确定一些原始字符串.长度大于散列,只给出散列. (2认同)