简体   繁体   English

C#增加字节数组用作整数计数器的最快方法?

[英]C# Fastest way to increment a byte array used as an integer counter?

I am using a segmented integer counter (byte array) in a parallel CTR implementation (encryption). 我在并行CTR实现(加密)中使用分段整数计数器(字节数组)。 The counter needs to be incremented in sizes corresponding to the blocks of data being processed by each processor. 需要将计数器的大小增加到与每个处理器正在处理的数据块相对应的大小。 So, the number needs to be incremented by more than a single bit value. 因此,该数字需要增加一个以上的位值。 In other words.. the byte array is acting as a Big Integer, and I need to increase the sum value of the byte array by an integer factor. 换句话说..字节数组起着大整数的作用,我需要将字节数组的和值增加一个整数倍。 I am currently using the methods shown below using a while loop, but I am wondering if there is a bit wise method (& | ^ etc), as using a loop seems very wasteful.. any ideas? 我目前正在使用以下所示的使用while循环的方法,但是我想知道是否存在一种明智的方法(&| ^等),因为使用循环似乎非常浪费..有什么想法吗?

private void Increment(byte[] Counter)
{
    int j = Counter.Length;
    while (--j >= 0 && ++Counter[j] == 0) { }
}

/// <summary>
/// Increase a byte array by a numerical value
/// </summary>
/// <param name="Counter">Original byte array</param>
/// <param name="Count">Number to increase by</param>
/// <returns>Array with increased value [byte[]]</returns>
private byte[] Increase(byte[] Counter, Int32 Count)
{
    byte[] buffer = new byte[Counter.Length];

    Buffer.BlockCopy(Counter, 0, buffer, 0, Counter.Length);

    for (int i = 0; i < Count; i++)
        Increment(buffer);

    return buffer;
}

The standard O(n) multi-precision add goes like this (assuming [0] is LSB): 标准O(n)多精度加法如下(假设[0]为LSB):

static void Add(byte[] dst, byte[] src)
{
    int carry = 0;

    for (int i = 0; i < dst.Length; ++i)
    {
        byte odst = dst[i];
        byte osrc = i < src.Length ? src[i] : (byte)0;

        byte ndst = (byte)(odst + osrc + carry);

        dst[i] = ndst;
        carry = ndst < odst ? 1 : 0;
    }
}

It can help to think of this is terms of grade-school arithmetic, which is really all it is: 可以想到的是小学数学的术语,这实际上就是全部:

  129
+ 123
-----

Remember, where you'd perform an add and carry for each digit, starting from the left (the least-significant digit)? 记住,从左数(最低有效数字)开始,您要对每个数字进行加和进位吗? In this case, each digit is a byte in your array. 在这种情况下,每个数字都是数组中的一个字节。

Rather than roll your own, have you considered using the arbitrary-precision BigInteger ? 您是否考虑过使用任意精度的BigInteger而不是自己动手? It was actually created specifically for .NET's own crypto stuff. 它实际上是为.NET自己的加密货币专门创建的。

I used a variation of Cory Nelsons answer that creates the array with the correct endian order and returns a new array. 我使用了Cory Nelsons答案的一种变体,以正确的字节序创建数组并返回一个新数组。 This is quite a bit faster then the method first posted.. thanks for the help. 这比最初发布的方法要快很多。.感谢您的帮助。

private byte[] Increase(byte[] Counter, int Count)
{
    int carry = 0;
    byte[] buffer = new byte[Counter.Length];
    int offset = buffer.Length - 1;
    byte[] cnt = BitConverter.GetBytes(Count);
    byte osrc, odst, ndst;

    Buffer.BlockCopy(Counter, 0, buffer, 0, Counter.Length);

    for (int i = offset; i > 0; i--)
    {
        odst = buffer[i];
        osrc = offset - i < cnt.Length ? cnt[offset - i] : (byte)0;
        ndst = (byte)(odst + osrc + carry);
        carry = ndst < odst ? 1 : 0;
        buffer[i] = ndst;
    }

    return buffer;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM