NET问答: 如何使用 C# 比较两个 byte[] 的相等性 ?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NET问答: 如何使用 C# 比较两个 byte[] 的相等性 ?相关的知识,希望对你有一定的参考价值。

咨询区

  • Hafthor

我现在业务中遇到了一个场景:如何简洁高效的判断两个 byte[] 的相等性?我现在是这么实现的,有一点繁琐:


static bool ByteArrayCompare(byte[] a1, byte[] a2)
{
    if (a1.Length != a2.Length)
        return false;

    for (int i=0; i<a1.Length; i++)
        if (a1[i]!=a2[i])
            return false;

    return true;
}

在 java 中是可以非常方便的实现。


java.util.Arrays.equals((sbyte[])(Array)a1, (sbyte[])(Array)a2);

回答区

  • aku

其实你可以使用 Linq 提供的 Enumerable.SequenceEqual 扩展方法达到同样的快捷效果。


using System;
using System.Linq;
...
var a1 = new int[] { 1, 2, 3};
var a2 = new int[] { 1, 2, 3};
var a3 = new int[] { 1, 2, 4};
var x = a1.SequenceEqual(a2); // true
var y = a1.SequenceEqual(a3); // false

顺便提醒一下:编译器运行时 会优化这种 loop 循环,所以你不需要担心什么性能问题。

  • plinth

可以借助 Windows 自带的系统函数帮你搞定,你要做的就是用 P/Invoke 调它,参考代码如下:


[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);

static bool ByteArrayCompare(byte[] b1, byte[] b2)
{
    // Validate buffers are the same length.
    // This also ensures that the count does not exceed the length of either buffer.  
    return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
}

或者你可以自己封装一段 unsafe 的代码。


// Copyright (c) 2008-2013 Hafthor Stefansson
// Distributed under the MIT/X11 software license
// Ref: http://www.opensource.org/licenses/mit-license.php.
static unsafe bool UnsafeCompare(byte[] a1, byte[] a2) {
  if(a1==a2) return true;
  if(a1==null || a2==null || a1.Length!=a2.Length)
    return false;
  fixed (byte* p1=a1, p2=a2) {
    byte* x1=p1, x2=p2;
    int l = a1.Length;
    for (int i=0; i < l/8; i++, x1+=8, x2+=8)
      if (*((long*)x1) != *((long*)x2)) return false;
    if ((l & 4)!=0) { if (*((int*)x1)!=*((int*)x2)) return false; x1+=4; x2+=4; }
    if ((l & 2)!=0) { if (*((short*)x1)!=*((short*)x2)) return false; x1+=2; x2+=2; }
    if ((l & 1)!=0) if (*((byte*)x1) != *((byte*)x2)) return false;
    return true;
  }
}

点评区

plinth 大佬的想法别出心裁,借助现存强大的 Windows 系统函数,免去了很多重复的业务逻辑,简单粗暴又高效,学习了。

以上是关于NET问答: 如何使用 C# 比较两个 byte[] 的相等性 ?的主要内容,如果未能解决你的问题,请参考以下文章

.NET如何快速比较两个byte数组是否相等

NET问答: 如何使用 C# 直接从 JSON String 中提取特定值 ?

没有绑定检查的 C# byte[] 比较

NET问答: 如何将十六进制的 #FFDFD991 转成 C# 中的 Color 类?

NET问答: 如何用 C# 计算相对时间 ?

C#如何把16进制字符串转成值相等的byte数组?