我正在研究一个程序,该程序将根据数据和正确数据的哈希来修复数据损坏。即使只处理几个字节的数据,它在大约4或5位被破坏后开始变慢,所以我想我会迭代而不是递归。在做了一些研究之后,我发现我可以使用堆栈来完成这项工作。我目前无法找到正确的位置来弹出堆栈中的变量。这是原始方法。
private static void fixFile(byte[] data, byte[] hash, byte[] correctHash, MessageDigest hasher, long depth)
{
int len = data.length;
outer: for(int i = 0; i < len; i++)
{
byte origVal = data[i];
for(int j = 0; j < 8; j++)
{
data[i] = (byte) (data[i] ^ (1 << j));
if(depth > 1)
fixFile(data, hash, correctHash, hasher, depth - 1);
hash = hasher.digest(data);
if(!Arrays.equals(correctHash, hash))
data[i] = origVal;
else
break outer;
}
}
}
这是修改后的方法,我试图让它迭代。
private static void fixFile(byte[] data, byte[] hash, byte[] correctHash, MessageDigest hasher, long depth)
{
Stack stack = new Stack<Integer>();
int len = data.length;
outer: for(int i = 0; i < len; i++)
{
byte origVal = data[i];
for(int j = 0; j < 8; j++)
{
data[i] = (byte) (data[i] ^ (1 << j));
if(depth > 1)
{
stack.push(depth);
stack.push(i);
stack.push(j);
depth--;
i = -1;
j = 0;
continue outer;
}
else
{
// where do I put this to make it work.
j = stack.pop();
i = stack.pop();
depth = stack.pop();
}
hash = hasher.digest(data);
if(!Arrays.equals(correctHash, hash))
data[i] = origVal;
else
break outer;
}
}
}
答案 0 :(得分:0)
我认为你的递归方法对于这个问题是理想的,所有的时间都将用在摘要函数中。
但是,当您修复深度位时,您可以在程序速度上获得因子(深度)改进。 (因此,对于6位,这将使程序变为6 * 5 * 4 * 3 * 2 * 1 =快720倍。)
问题是您当前的代码当前切换数据中的深度位,但是按任何顺序。即,当它切换三位时,它将尝试切换位1,2,3和2,1,3和3,1,2和3,2,1以及1,3,2和2,3,1(以及其他许多位)选择)。请注意,在每种情况下,切换完全相同的3位,因此没有必要测试它们。
您可以通过将其他参数传递给代码来说明最后一位被切换的位置(即传入i和j作为i_base和j_base),然后只允许您的代码在以后更换新位时来解决此问题。在数据中的位置(即如果i> i_base ||(i == i_base&amp;&amp; j&gt; j_base))。