通过位移合并两个可变长度的字节数组

时间:2018-07-12 11:53:42

标签: c# arrays bit-shift

我有两个字节数组,它们具有可变的长度,但总是加起来最多为8个字节。这些需要组合在一起很长。我可以通过创建一个字节数组并复制所需的数据来做到这一点。但是我当时认为通过位移也可以做到这一点。我一直在尝试(只用一个长度简化):

        var bytes1 = new byte[] { 1, 2, 3, 4, 5, 6, 7 };
        var bytes2 = new byte[] { 8 };
        unsafe
        {
            fixed (byte* b1 = bytes1)
            {
                fixed (byte* b2 = bytes2)
                {
                    ulong* bl1 = (ulong*)b1;
                    ulong v = (*bl1<< 8)  | (*b2);

                    var bytes = bytes1.Concat(bytes2).ToArray();

                    // These two are different:
                    Console.WriteLine(v); 
                    Console.WriteLine(BitConverter.ToUInt64(bytes, 0));
                }
            }
        }

我知道Concat可以工作,但是我也想这样做。

1 个答案:

答案 0 :(得分:0)

首先,(ulong*)b1是超出范围的读取,因为数组的长度为7并且sizeof(ulong) == 8。下次读取也以这种方式被破坏。对齐也是一个问题。我没有办法挽救这种方法。您可以读取4个字节,然后读取2个字节,然后再读取1个字节(如果您确实在寻找性能)。

我将遍历数组并移入每个字节:

ulong result = 0;

void MergeArray(byte[] bytes) {
 foreach (var b in bytes) {
  result = result << 8 | (ulong)b;
 }
}

MergeArray(bytes1);
MergeArray(bytes2);

使用本地功能进行代码共享。

如果数组长度支持该大小的读取,则可以通过将4个字节作为第一个块来提高性能。然后,先获取2,再获取1。这样一来,即使没有循环,操作次数也将最小化。

这是否好取决于您对性能的需求,必须以代码易读性为代价。