是否可以进行此算法的逆过程?
int EDI = 0x1505;
for( int i = 0; i < lstrlen(dir); i++ )
{
if ( dir[i] != '.' && dir[i] != '\' )
{
EDX = EDI * 32;
EDX = EDX + EDI;
EDX = EDX + dir[i];
EDI = EDX;
}
}
dir
是一个字符串,例如,当dir
是&#34; data \ etcobject \ damagecri.nif&#34;该函数的输出将是:1C9EA36C
。
有没有办法检索只给出输出编号的原始字符串?
答案 0 :(得分:4)
你无法扭转这个功能,因为它是有损的;它的输出位数少于输入位,因此不可避免地会有多个输入返回相同的输出。例如,它会忽略.
和/
,因此输入ab
,a/b
和a.b
将是相同的。
即使你忽略了.
和/
,也没有办法;您正在将字符串转换为整数; waaaaaay比整数更多的字符串,所以不可避免地会有多个字符串产生相同的整数。
答案 1 :(得分:1)
有没有办法检索只给出输出编号的原始字符串?
一般来说:不。
请注意
EDX = EDI * 32;
EDX = EDX + EDI;
// same as
EDX = EDI *33'
考虑长度为2的2个字符串A
和B
。
The `EDI` generated are
EDI(A) = 33*A[0] + A[1] + constant
EDI(B) = 33*B[0] + B[1] + constant
with `A[0] == 2, A[1] == 3` we get `33*2 + 3 + constant` or `69 + constant`
with `B[0] == 1, B[1] == 36` we get `33*1 + 36 + constant` or `69 + constant`
因此,对于EDI
69 + constant
,我们无法区分2个字符串原件(或许多其他候选者)。
另一种看待它的方法是我们假设只使用A-Z
:然后使用7个或更多字母字符,有超过pow(26,7) or 8,031,810,176
个组合和int
(假设32- bit)最多只有4,294,967,296
组合。所以没有办法将所有7个长字符串区分为32位int
。
答案 2 :(得分:0)
此:
EDX = EDI * 32;
EDX = EDX + EDI;
EDX = EDX + dir[i];
EDI = EDX;
显然与:
相同 EDX = EDX * 33 + dir[i];
因此当dir [i]在33的范围内(例如0-32或97-129)并且EDX不溢出时,只能反转字符串。
所以,如果你可以假设字符串只有负数(ascii 97-122,那么它可能是:
VAL
ch = VAL % 33
ch = ch + n*33
。选择n以使ch
进入97-129范围,这是下一个字符。VAL
中减去此字符,然后除以33:VAL = (VAL - ch) / 33
如果您觉得计算出的char不正确,可以通过将ch
带入ascii范围的其他范围(例如数字,大写字母)来进一步改进。但这使得算法具有启发性。
另一种方法:如果您有一个候选字符串列表(或者您可以生成一个),那么您可以使用它来提供算法并将其与数字进行比较。