Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#字节数组比较_C#_.net_Bytearray - Fatal编程技术网

C#字节数组比较

C#字节数组比较,c#,.net,bytearray,C#,.net,Bytearray,我使用.NET3.0在C#中使用了两个字节数组 比较两字节数组中每个元素是否包含相同内容的“最有效”方法是什么 例如,字节数组{0x1,0x2}与{0x1,0x2}相同。但是字节数组{0x1,0x2}和字节数组{0x2,0x1}不一样。您可以使用以下方法: 如评论中所述,SequenceEqual需要.NET 3.5(或者,如果您使用的是VS2008并针对早期版本的框架)。那么,您可以使用: public static bool ByteArraysEqual(byte[] b1, byte[]

我使用.NET3.0在C#中使用了两个字节数组

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

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

您可以使用以下方法:

如评论中所述,
SequenceEqual
需要.NET 3.5(或者,如果您使用的是VS2008并针对早期版本的框架)。

那么,您可以使用:

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;
}
publicstaticboolbytearraysequal(字节[]b1,字节[]b2)
{
如果(b1==b2)返回true;
如果(b1==null | | b2==null)返回false;
如果(b1.Length!=b2.Length)返回false;
对于(int i=0;i
(我通常对所有东西都使用大括号,但我想我应该尝试一下这种布局风格,只是为了改变一下…)

这有一些
SequenceEqual
无法(或不)执行的优化,例如前端长度检查。直接数组访问也将比使用枚举器更有效率

诚然,在大多数情况下,这不太可能产生重大影响


在非托管代码中,您可以通过让它一次比较32或64位而不是8位来提高速度,但我不想在运行时编写这种代码。

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


Jon提到使用不安全的代码一次比较多个字节,所以我不得不试一试:

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;
}

安全代码得到了很好的优化(例如,编译器知道它不必检查索引边界),因此我不认为不安全代码会更快。任何显著的差异都来自于同时对几个字节进行比较的能力。

< P>如果你不太关心性能,你可以考虑<代码> iSturtualAlcabdie。 中支持的.NET框架:4.5,4

结构相等意味着两个对象相等,因为它们的值相等。它不同于引用等式

例如:

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


  • 我认为这是最有效的方法。从执行时间的角度来说不是。@Veton:这肯定是打字最少的方法!请参阅Jon的答案以获得一些额外的优化。(尝试通过SequenceEqual将包含1000000个条目的字节数组与包含1000001个条目的字节数组进行比较。在注意到它们的长度不同之前,它会一直到最后…)这在.NET 3.0中也不起作用(没有LINQBridge之类的东西),如问题中所要求的那样。。。虽然OP可能意味着.NET 3.5.0适用于大型阵列,比如10k,并行化是一种有效的优化还是线程开销太大?你对此有何看法?@Lijo:我承认我从来没有完全理解过
    isttructuralequatable
    ,以及什么时候合适。好概念的重复,尽管代码没有编译:“无法分配给'p1',因为它是一个'固定变量'”@Edward Brey:你是正确的,这不起作用。你需要在块内声明新指针以使其可更改。我已更正了代码。使用long(8字节)更快在comp中,甚至在32位机器上。给这篇文章一个要点:当我们使用最新版本的框架时,这可能是一种方法。
    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;
    }
    
    static bool ByteArrayCompare(byte[] a1, byte[] a2) 
    {
      IStructuralEquatable eqa1 = a1;
      return eqa1.Equals(a2, StructuralComparisons.StructuralEqualityComparer);
    }