这个算法的逆向!!!

bb_star_bb 2007-03-17 12:38:00
protected static final int getHash(byte [] data, int off, int len)
{
int k = 147;
try{

for(int l = off + len; l > off;)
k = k * 147 ^ data[--l];

return k;
}
catch(Throwable throwable){
return k;
}

}

如果给出一个int的值,如何反过来得到data的值呢。
征求算法!!!
...全文
419 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
For_suzhen 2007-03-18
  • 打赏
  • 举报
回复
学习学习,真是麻烦
maquan 2007-03-18
  • 打赏
  • 举报
回复
刚看到这个题目,我的第一反应就是:这个算法是不可逆的!

道理很简单,这应该是一个“摘要算法”,把一个任意长度的信息摘要成为一个固定宽度(本算法中就是一个 int 的大小)的值。我们知道,MD5 就是一个经典的摘要算法。

摘要算法当然是不可逆的。

然后,又仔细看了看这个算法,发现它是一个简单的递推算法,这样的话,在某些情况下也许是可以反推的。

我写了一段程序,把算法的过程显示了出来,这样,就很容易看出 k 的计算过程了。比如,当原字符串为 "src" 的时候,计算过程是这样的:

k c k*147 k*147^c
00000093 c 63 0000000000005469 000000000000540A
0000540A r 72 00000000003041BE 00000000003041CC
003041CC s 73 000000001BB5C824 000000001BB5C857

很显然,如果在计算过程中,k 没有发生过溢出,那么,就是可以反推的(不过,即使这样,也必须有另一个前提,原字符只能是普通的 ASCII 字符)。

程序附在下面,其中 decode() 是反推的计算过程,尤其是其中的 guess() 就是用来推算每个字符的。

如果把 guess() 做得更复杂一点,也许能使反推的效果更好一点,但我相信那应该有更多的约束信息参与进来(或者人工干预)才可以,不会有确定性的结果。

BTW: 楼主是不是从哪个软件里摘出来的一段算法,准备做破解呀? @_-

package test;

public class Reverse {

protected static final int getHash(byte[] data, int off, int len) {
int k = 147;
try {
System.out.printf("%-8s\t%-2s\t%-16s\t%-16s\r\n", "k", "c", "k*147", "k*147^c");
for (int l = off + len; l > off;) {
int c = data[--l];
System.out.printf("%08X\t%c %02X\t%016X\t%016X\r\n", k, c, c, k*147, ((long)k*147)^c);
k = (k * 147) ^ c;
}
return k;
} catch (Throwable throwable) {
return k;
}
}

protected static char guess(int k) {
char c = '?';
int b = k / 147;
for (int i=0; i<2; i++) {
int k2 = (b+i) * 147;
c = (char)(k2 ^ k);
System.out.printf("guess: %d: %08X\t%08X\t%02X\r\n", i, k, k2, (byte)c);
if (c >= ' ' && c <= '~') break;
}
return c;
}

protected static String decode(int k) {
String plain = "";
int i = 0;
while (true) {
char c = guess(k);
plain += c;
k = (k^c)/147;
if (++i > 10 || k==147) break;
}

return plain;
}

public static void main(String[] args) {
String sample = "src";
// "id", "title", "align", "src", "alt", "href",
// "value", "type", "name", "maxlength", "size", "method"
byte[] ba = sample.getBytes();
int code = getHash(ba, 0, ba.length);
System.out.printf("%s: 0x%08x\r\n", sample, code);
System.out.println(decode(code));
}
}
littlegang 2007-03-18
  • 打赏
  • 举报
回复
如果全是字母a-z,并且长度不大,应该用maquan('ma:kju) 的方法可以了的
0轰隆隆0 2007-03-17
  • 打赏
  • 举报
回复
无论三个参数取什么值,k的值永远都不会变,永远都是147
issgates 2007-03-17
  • 打赏
  • 举报
回复
闻到分香,我就来了,帮顶,接分。
sunny3106 2007-03-17
  • 打赏
  • 举报
回复
不太清楚,帮顶!
bb_star_bb 2007-03-17
  • 打赏
  • 举报
回复
强烈要求达人出手。分数可以一直加到1000。
bb_star_bb 2007-03-17
  • 打赏
  • 举报
回复
提供一些例子。望各位出手
30431e id
26ef2ce3 title
bea8f922 align
1bb5c857 src
1bbc18f0 alt
ea6d7c86 href
2880a8e2 value
e9a39a2b type
e9a04f90 name
2dc86ad3 maxlength
e9a7395a size
eb7b28b6 method
0轰隆隆0 2007-03-17
  • 打赏
  • 举报
回复
灵活性太大,有逆解;但我没有思路,帮你顶下了
  • 打赏
  • 举报
回复
up
For_suzhen 2007-03-17
  • 打赏
  • 举报
回复
看你的程序
k = 147的(1 + data[len+off-1] + data[len+off-2] +........data[off] )次方
输入一个int值,可以得到data[len+off-1] + data[len+off-2] +........data[off]的和,但是如何得到data[]中每个元素的值,我没办法了,等待高手吧,可能我这样没解,或者说是个矩阵解,等待高手吧,数学太差了.而且你的off和len会给出来吗?
bb_star_bb 2007-03-17
  • 打赏
  • 举报
回复
0x69a6d9dd

这是一个结果,怎么得到data。。。
0轰隆隆0 2007-03-17
  • 打赏
  • 举报
回复
刚才看错了;

当 off 的取值是 0,-1或者-2的时候才会有真真的值

而其他条件下都是147
0轰隆隆0 2007-03-17
  • 打赏
  • 举报
回复
绝妙的算法;

佩服了~~
bb_star_bb 2007-03-17
  • 打赏
  • 举报
回复
这个算法不可逆吗?

For_suzhen 2007-03-17
  • 打赏
  • 举报
回复

无论三个参数取什么值,k的值永远都不会变,永远都是147

=======================================================
你凭什么这样说
For_suzhen 2007-03-17
  • 打赏
  • 举报
回复
关键最后求解的是
x1+x2+x3+.....xn=C
一个方程,n个未知数,怎么求阿
x1,x2只见又没什么规律
bb_star_bb 2007-03-17
  • 打赏
  • 举报
回复
off和len都是给定的。
例如data[]的长度的长度为3。
off = 0,len = data.length


如果给出结果,也就是int,怎么逆向得到data[]的值呢
dovelee 2007-03-17
  • 打赏
  • 举报
回复
bang ding

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧