对于我的问题n = 16,但也会赞赏一般答案。
所以我有一个字节数组:
#define PER_CPU_ALIGNED_SECTION "..shared_aligned"
#define PER_CPU_BASE_SECTION ".data..percpu"
#define __PCPU_ATTRS(sec)
__percpu __attribute__((section(PER_CPU_BASE_SECTION sec)))
PER_CPU_ATTRIBUTES
我的问题是我希望迭代这个数组中每个元素的所有可能值。我知道这需要很长时间,而且我不打算实际完成这个循环,只是为了制作一个至少会尝试这个循环的循环。
所以例如:
第一次迭代:
byte[] key;
第二次迭代:
//Math.Pow(2,128) is the max no. of iterations right?
byte[] key;
for(int i = 0; i < Math.Pow(2,128); i++)
{
key = new byte[16] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
}
第三次迭代:
//Math.Pow(2,128) is the max no. of iterations right?
byte[] key;
for(int i = 0; i < Math.Pow(2,128); i++)
{
key = new byte[16] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
}
最后一次迭代:
//Math.Pow(2,128) is the max no. of iterations right?
byte[] key;
for(int i = 0; i < Math.Pow(2,128); i++)
{
key = new byte[16] {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
}
显然我刚刚对上面的数组进行了硬编码。我需要一种以适当的方式做到这一点的方法。同样,我知道很多不同的组合。我只需要一种开始迭代所有可能值的方法。我怎么能在循环中做到这一点?
即。我应该用循环体取代,以便迭代16字节数组的所有可能值。
我尝试了什么:
在循环体中,我尝试了以下内容:
//Math.Pow(2,128) is the max no. of iterations right?
byte[] key;
for(int i = 0; i < Math.Pow(2,128); i++)
{
key = new byte[16] {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
}
显然错了,只会测试一小部分可能的值。只需尝试i = 0,...,255,然后在i = 256时重新开始 - > (字节)i = 0。
我怀疑我需要更多的嵌套。可能多达16个嵌套循环,这听起来很疯狂,可能是错的?我无法理解这个问题,任何帮助都会非常感激!
目的: 这个问题的目的是证明蛮力密码分析在实践中是多么低效。我的程序的其余部分工作,我只是停留在这个循环中。
答案 0 :(得分:4)
如果您没有意识到:16个字节是Guid的大小或标准加密密钥大小的大小。有这么多组合,你甚至不能枚举一小部分。如果你在1000台机器上并行化并等待一年,也许你可以枚举最后8个字节。
您可以通过运行从0到ulong.MaxValue
的for循环来轻松完成此操作。我提交这个作为答案,因为这个非常简单的想法允许你开始枚举,并且基本上没有达到你完成的程度。
for (ulong i = 0; i < ulong.MaxValue; i++) {
var bytes = new [] {
0, 0, 0, 0, 0, 0, 0, 0
, (byte)(i >> (7 * 8))
, (byte)(i >> (6 * 8))
, (byte)(i >> (5 * 8))
//...
, (byte)(i >> (0 * 8)) };
}
或者,只使用16个嵌套for循环。我根本不认为这是疯了,因为它太简单了,显然是正确的。
答案 1 :(得分:1)
这是一个示例代码,没有任何异常处理,并且模拟像您提到的那样的计数器效率低下
public static void NextIteration(byte[] input)
{
if (input.All(x => x == 255))
throw new InvalidOperationException("there is no iteration left");
var converted = input.Select(x => (int) x).ToArray();
converted[0]++;
for (var i = 0; i < converted.Length; i++)
{
if (converted[i] == 256)
{
converted[i] = 0;
converted[i + 1]++;
}
}
for (var i = 0; i < input.Length; i++)
{
input[i] = (byte) converted[i];
}
}