如何逐步遍历大小为n的字节数组的所有可能值?

时间:2015-06-13 16:40:00

标签: c# .net loops byte bytearray

对于我的问题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个嵌套循环,这听起来很疯狂,可能是错的?我无法理解这个问题,任何帮助都会非常感激!

目的: 这个问题的目的是证明蛮力密码分析在实践中是多么低效。我的程序的其余部分工作,我只是停留在这个循环中。

2 个答案:

答案 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];
    }
}