我有byte[] testKey = new byte[8];
这显然从所有字节开始为0.我希望遍历所有字节并在循环的每次迭代中递增1,因此最终我将完成字节数组的所有可能性。我也想尽快做到这一点。是的,我正在努力写一个野蛮的人。
更新我得到了不安全的方法,它是最快的。但是,根据我的计算,使用.Net DESCryptoServiceProvider对每个密钥进行DES加密需要76,000,000,000年。 10,000次加密需要1.3秒。感谢有史以来最无用的问题的所有令人敬畏的答案!
答案 0 :(得分:12)
顺便说一句;需要批次处理来检查2 ^ 64个选项......
嗯,最快的方式可能只是使用Int64
(又名long
)或UInt64
(ulong
),并使用++
?你真的需要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个字节转换为完全长,并递增它。 几乎完成转换回字节。 这是系统中最快的方式