增加一个字节[]

时间:2009-09-18 11:54:42

标签: c# .net

我有byte[] testKey = new byte[8];

这显然从所有字节开始为0.我希望遍历所有字节并在循环的每次迭代中递增1,因此最终我将完成字节数组的所有可能性。我也想尽快做到这一点。是的,我正在努力写一个野蛮的人。

更新我得到了不安全的方法,它是最快的。但是,根据我的计算,使用.Net DESCryptoServiceProvider对每个密钥进行DES加密需要76,000,000,000年。 10,000次加密需要1.3秒。感谢有史以来最无用的问题的所有令人敬畏的答案!

11 个答案:

答案 0 :(得分:12)

顺便说一句;需要批次处理来检查2 ^ 64个选项......

嗯,最快的方式可能只是使用Int64(又名long)或UInt64ulong),并使用++?你真的需要byte[]吗?

作为一个hacky替代品,如何:

Array.Clear(data, 0, data.Length);
while (true)
{
  // use data here
  if (++data[7] == 0) if (++data[6] == 0)
    if (++data[5] == 0) if (++data[4] == 0)
      if (++data[3] == 0) if (++data[2] == 0)
        if (++data[1] == 0) if (++data[0] == 0) break;
}

我能想到的唯一另一种方法是使用不安全的代码与数组交谈,就像它是一个int64 ......凌乱。

unsafe static void Test() {
    byte[] data = new byte[8];
    fixed (byte* first = data) {
        ulong* value = (ulong*)first;
        do {
            // use data here
            *value = *value + 1;
        } while (*value != 0);
    }
}

答案 1 :(得分:7)

这是增加数组值的方法:

int index = testKey.Length - 1;
while (index >= 0) {
   if (testKey[index] < 255) {
      testKey[index]++;
      break;
   } else {
      testKey[index--] = 0;
   }
}

在此代码之后index为-1时,您已经迭代了所有组合。

这比使用BitConverter要快一些,因为它不会为每次迭代创建一个新数组。

编辑:
小型性能测试表明,这比使用BitConverter快1400倍......

答案 2 :(得分:4)

这是一个很棒的问题!这是一种没有不安全代码的方法:

public struct LongAndBytes
{
    [FieldOffset(0)]
    public ulong UlongValue;
    [FieldOffset(0)]
    public byte Byte0;
    [FieldOffset(1)]
    public byte Byte1;
    [FieldOffset(2)]
    public byte Byte2;
    [FieldOffset(3)]
    public byte Byte3;
    [FieldOffset(4)]
    public byte Byte4;
    [FieldOffset(5)]
    public byte Byte5;
    [FieldOffset(6)]
    public byte Byte6;
    [FieldOffset(7)]
    public byte Byte7;

    public byte[] ToArray()
    {
        return new byte[8] {Byte0, Byte1, Byte2, Byte3, Byte4, Byte5, Byte6, Byte7};
    }
}


// ...

    LongAndBytes lab = new LongAndBytes();

    lab.UlongValue = 0;
    do {
        // stuff
        lab.UlongValue++;
    } while (lab.ULongValue != 0);

每个成员Byte0 ... Byte7重叠ulong并分享其成员。这不是一个阵列 - 我试着用它来研究并且结果并不令人满意。我打赌有人知道要做到这一点的神奇宣言。我可以为P / Invoke做到这一点,但不能在.NET中使用,因为数组是一个对象。

答案 3 :(得分:3)

byte [8]本质上是一个ulong但是如果你真的需要它是byte [8]你可以使用

byte[] bytes = new byte[8];
ulong i = 0;
bytes = BitConverter.GetBytes(i);

答案 4 :(得分:2)

您可以使用位运算符提取字节:

byte[] bytes = new byte[8];
for (ulong u = 0; u < ulong.MaxValue; u++)
{
    bytes[0] = (byte)(u & 0xff);
    bytes[1] = (byte)((u >> 8) & 0xff);
    bytes[2] = (byte)((u >> 16) & 0xff);
    bytes[3] = (byte)((u >> 24) & 0xff);
    bytes[4] = (byte)((u >> 32) & 0xff);
    bytes[5] = (byte)((u >> 40) & 0xff);
    bytes[6] = (byte)((u >> 48) & 0xff);
    bytes[7] = (byte)((u >> 56) & 0xff);
    // do your stuff...
}

这不那么'hackish',因为它首先在无符号的64位整数上运行,然后提取字节。但要注意CPU的结束。

答案 5 :(得分:1)

for (UInt64 i = 0; i < UInt64.MaxValue; i++)
{
    byte[] data = BitConverter.GetBytes(i)
}

答案 6 :(得分:1)

byte[] array = new byte[8];
int[] shifts = new int[] { 0, 8, 16, 24, 32, 40, 48, 56 };    
for (long index = long.MinValue; index <= long.MaxValue; index++)
{
    for (int i = 0; i < 8; i++)
    {
        array[i] = (byte)((index >> shifts[i]) & 0xff);
    }
    // test array
}

答案 7 :(得分:1)

for (int i = 0; i < bytes.Length & 0 == ++bytes[i]; i++);

应该与不安全的方法一样快,并允许任何大小的数组。

答案 8 :(得分:0)

简单迭代:

static IEnumerable<byte[]> Iterate(int arrayLength) {
    var arr = new byte[arrayLength];
    var i = 0;
    yield return arr;
    while (i < arrayLength)
    {
        if (++arr[i] != 0)
        {
            i = 0;
            yield return arr;
        }
        else i++;
    }
}

static void Main(string[] args)
{
    foreach (var arr in Iterate(2))
    {
        Console.Write(String.Join(",", arr.Select(x => $"{x:D3}")));
        Console.WriteLine();
    }
}

答案 9 :(得分:0)

很抱歉,后期的帖子,但我也需要所描述的功能,并以一种非常简单的方式实现它。也许对其他人也有用:

private byte[] IncrementBytes(byte[] bytes)
{
    for (var i = bytes.Length - 1; i >= 0; i--)
    {
        if (bytes[i] < byte.MaxValue)
        {
            bytes[i]++;
            break;
        }
        bytes[i] = 0;
    }
    return bytes;
}

答案 10 :(得分:-1)

BitConverter.ToInt64 / BitConverter.GetBytes - 将8个字节转换为完全长,并递增它。 几乎完成转换回字节。 这是系统中最快的方式