有人能帮我找出这是什么类型的算法吗?
public class hf1 {
public static final String[] f3650a = {"0sFU@W>Ao*BT64?[L5aONSK.'"...};
public static final String[] f3651b = {" \bB\u0017\u001e)YBN\u001eT/\u001e4V\u0001ZT/6VV"...};
public static final String[] f3652c = {"\u0000\u0000\u0013\u00006\u0000\\\u0000\u0000¢\u0000¹\u0000¿\u0000"...};
public static String m5192a(int i) {
int i2 = i / 4096;
int i3 = i % 4096;
int i4 = i + 1;
int i5 = i4 / 4096;
int i6 = i4 % 4096;
String[] strArr = f3652c;
String str = strArr[i2];
String str2 = strArr[i5];
int i7 = i3 * 2;
int charAt = ((str.charAt(i7 + 1) & 65535) << 16) | (str.charAt(i7) & 65535);
int i8 = i6 * 2;
int charAt2 = ((str2.charAt(i8 + 1) << 16) | str2.charAt(i8)) - charAt;
char[] cArr = new char[charAt2];
for (int i9 = 0; i9 < charAt2; i9++) {
int i10 = charAt + i9;
int charAt3 = f3651b[i10 / 8192].charAt(i10 % 8192) & 65535;
cArr[i9] = f3650a[charAt3 / 8192].charAt(charAt3 % 8192);
}
return new String(cArr);
}
}
如果调用m5192a(1)并将任何int索引作为参数传递,代码将返回一个字符串。就像在源代码中隐藏普通字符串一样。
有人知道可能的反码吗?把普通字符串转换成这个?这是一种已知的有名字的技术吗?
1条答案
按热度按时间7rfyedvj1#
我不确定“已知的有名称的技术”——也许像“逆函数”或“双向化”这样的关键词可能会有所帮助,例如,在纯函数语言中,是否有一种算法来获得逆函数?
对于这个特定函数,幸运的是,只要
f365xx
字符串常量遵循某些属性。注意cArr
一个接一个地填充,每个字符相互独立。我们可以尝试使用字符和字符串长度来解码输入i
. 明确地,一个字符就可以让我们成为
i10
,这将为我们提供charAt
. 重复所有的角色,希望只有一个候选人将工作的每一个字符,候选人将给我们i7
/i2
->i2
/i3
->i
如果弦是“仁慈的”。如果字符串不仁慈,那么字符串的长度将给我们的候选人
charAt2
再加上charAt
,将为我们提供i8
/i6
. 希望只有一对候选人i6
/i8
->i5
/i6
-> ->i4
->i
如果字符串常量是仁慈的。如果字符串仍然不仁慈,那么它是无法解决的,因为函数不是一对一的。
我现在将概述这两个要点的算法,但作为免责声明,我还没有测试过这一点,它只是伪代码。
从一个角色
假设你从第一个角色开始,
cArr[0]
. 如果我们关注for循环中的3行,然后我们就可以
charAt3
找到了哪里cArr[0]
出现在f3650a
. 例如,注意我们过滤掉了
indexCandidate >= 8192
以及charAt3candidate >= 65536
由于模和位and使得更大的值变得不可能(x & 65535 == x % 65536
因为65536=2^16)。做一个类似的过程来寻找候选人
i10
和减法i9
让候选人charAt
. 如果您有多个候选角色,请对中的每个角色重复此过程cArr
只保留charAt
对中的每个字符都有效cArr
. 即使在每一个字符重复cArr
,你可能还有很多候选人。每一位候选人
charAt
,使用表达式的右半部分charAt
:charAt % 65536 = (str.charAt(i7) & 65535)
结合str = f3652c[i2]
试图找到i2
/i7
和我们想找的一样charAt3
以及i10
. 注意表达式的左半部分,((str.charAt(i7 + 1) & 65535) << 16)
,无所谓(目前)。希望并祈祷这只给你一个可能的选择i2
/i7
. 如果是,用它来找到i2
/i3
->i
. 如果有多个选项,那么我们必须尝试使用字符串的长度。从绳子的长度
绳子的长度给了我们
charAt2
,我们可以使用与以前类似的过程来查找i8
以及str2
(i5
). 注意:在这个过程中,我们必须尝试每一个可能的候选人charAt
. 希望只有一对候选i8
/i5
剩下的。如果是,用它来找到i5
/i6
->i4
->i
. 如果有多个候选函数,那么函数不是一对一的,不可能反转。祝你好运!