C#字节数组比较(C# byte array comparison)

2019-07-05 09:51发布

我使用.NET 3.0的C#两个字节数组。

什么是“最有效”的方式来比较两个字节数组是否包含每个元素的相同的内容?

例如,字节数组{0x1, 0x2}相同{0x1, 0x2} 但是字节数组{0x1, 0x2}和字节数组{0x2, 0x1}是不一样的。

Answer 1:

嗯,你可以使用:

public static bool ByteArraysEqual(byte[] b1, byte[] b2)
{
    if (b1 == b2) return true;
    if (b1 == null || b2 == null) return false;
    if (b1.Length != b2.Length) return false;
    for (int i=0; i < b1.Length; i++)
    {
        if (b1[i] != b2[i]) return false;
    }
    return true;
}

(我通常使用大括号的一切,但我想我会用这个布局风格实验只是为了改变...)

这具有几个最佳化其SequenceEqual不能(或不)执行-例如向上前长度检查。 直接数组访问也将是一个有点比使用枚举更有效。

诚然,这是不太可能在大多数情况下,显著区别...

您可以通过使其在一个时间,而不是8比32个或64位可能使其更快非托管代码-但我不喜欢代码的飞行。



Answer 2:

您可以使用SequenceEqual方法:

bool areEqual = firstArray.SequenceEqual(secondArray);

正如评论所说, SequenceEqual需要.NET 3.5(或LINQBridge如果你使用VS2008和定位框架的早期版本)。



Answer 3:

乔恩提到一次使用不安全的代码比较多个字节,所以我不得不给它一个去:

public unsafe bool ByteArraysEqual(byte[] b1, byte[] b2) {
   if (b1 == b2) return true;
   if (b1 == null || b2 == null) return false;
   if (b1.Length != b2.Length) return false;
   int len = b1.Length;
   fixed (byte* p1 = b1, p2 = b2) {
      int* i1 = (int*)p1;
      int* i2 = (int*)p2;
      while (len >= 4) {
         if (*i1 != *i2) return false;
         i1++;
         i2++;
         len -= 4;
      }
      byte* c1 = (byte*)i1;
      byte* c2 = (byte*)i2;
      while (len > 0) {
         if (*c1 != *c2) return false;
         c1++;
         c2++;
         len--;
      }
   }
   return true;
}

该安全码被漂亮优化(编译器知道它没有检查例如指数边界),所以我不希望在不安全的代码是非常快的多。 任何显著差异将来自一次比较几个字节的能力。



Answer 4:

如果你不是太在意性能,可以考虑IStructuralEquatable

.NET框架支持:4.5,4

结构相等意味着两个对象是相等的,因为它们具有相同的值。 它不同于参考平等。

例:

static bool ByteArrayCompare(byte[] a1, byte[] a2) 
{
  IStructuralEquatable eqa1 = a1;
  return eqa1.Equals(a2, StructuralComparisons.StructuralEqualityComparer);
}

参考

  1. 有什么问题就IStructuralEquatable和IStructuralComparable解决?
  2. 为什么不IStructuralEquatable和IStructuralComparable通用?
  3. IStructuralEquatable接口


Answer 5:

如果你希望它是真快,你可以使用不安全的代码(这并不总是可能的):

    public static bool ArraysEqual(byte[] b1, byte[] b2)
    {
        unsafe
        {
            if (b1.Length != b2.Length)
                return false;

            int n = b1.Length;

            fixed (byte *p1 = b1, p2 = b2)
            {
                byte *ptr1 = p1;
                byte *ptr2 = p2;

                while (n-- > 0)
                {
                    if (*ptr1++ != *ptr2++)
                        return false;
                }
            }

            return true;
        }
    }


文章来源: C# byte array comparison