【问题标题】:Checking equality for two byte arrays检查两个字节数组的相等性
【发布时间】:2013-08-30 15:20:30
【问题描述】:

我正在检查两个字节数组的相等性,我需要一些帮助,因为即使数组应该相等,我也返回 false。

在我的调试中,我可以看到 a1 和 b1 是相等的,但它没有进入 while 循环来增加 i。

public bool Equality(byte[] a1, byte[] b1)
{
    int i;
    bool bEqual;
    if (a1.Length == b1.Length)
    {
        i = 0;
        while ((i < a1.Length) && (a1[i]==b1[i]))
        {
            i++;
        }

        if (i == a1.Length)
        {
            bEqual = true;
        }
    }
    return bEqual;
}

这总是返回 false:(a1[i]==b1[i])

【问题讨论】:

  • 您的退货单在哪里?
  • hashB 应该是 b1 吗?
  • 据我所知它没有返回任何东西
  • 哪个框架版本?
  • 在我们回答完问题后,您不能一直更改这么多问题,所有回答都会在问题的不同版本之间混淆。将其作为新问题发布...

标签: c#


【解决方案1】:

您需要在某处添加返回值。这应该有效:

public bool Equality(byte[] a1, byte[] b1)
{
   int i;
   if (a1.Length == b1.Length)
   {
      i = 0;
      while (i < a1.Length && (a1[i]==b1[i])) //Earlier it was a1[i]!=b1[i]
      {
          i++;
      }
      if (i == a1.Length)
      {
          return true;
      }
   }

   return false;
}

但这要简单得多:

return a1.SequenceEqual(b1);

或者,您可以使用 .NET 4 中的 IStructuralEquatable

return ((IStructuralEquatable)a1).Equals(b1, StructuralComparisons.StructuralEqualityComparer)

如果性能是一个问题,我建议重写您的代码以使用 Binary 类,该类专门针对这种用例进行了优化:

public bool Equality(Binary a1, Binary b1)
{
    return a1.Equals(b1);
}

我的机器上的快速基准测试提供了以下统计信息:

Method                   Min         Max         Avg
binary equal:          0.868       3.076       0.933    (best)
for loop:              2.636      10.004       3.065
sequence equal:        8.940      30.124      10.258
structure equal:     155.644     381.052     170.693

下载this LINQPad file 自行运行基准测试。

【讨论】:

  • 我正在使用它来比较两个不同的文件并返回差异(添加或删除了哪些记录),而不是它正确运行和循环我没有收到关于文件差异的返回消息删除了哪个文件的记录
  • @Masriyah 所以你真正想做的是实现一个差异算法?这是一项与简单检查相等性完全不同的任务。我建议您查看 Google 的 diff-match-patch 库。
  • 我继续上传了与此相关的代码的其他部分。也许你可以看看并指出一些事情。我整天都在绕圈子。谢谢
  • 就第一个解决方案而言,从逻辑上讲,OP 的代码与此代码之间没有区别。 OP 只是忘记将 bEqual 初始化为 false,如果这样做也会产生相同的结果。
  • 我发布了一个新问题,如果你可以看看。 stackoverflow.com/questions/18473580/…
【解决方案2】:

要检查相等性,你可以写:

var areEqual =  a1.SequenceEqual(b1);

【讨论】:

  • 这在技术上需要 LINQ,这可能与他的框架不匹配
  • 但如果它确实与他的框架匹配,那么它是一种更好的方法。
  • @Moop Linq 已经存在 6 年了,现在肯定大多数人都至少升级到了 framework 3.5。
  • @MikePrecup 在今天这个时代,除非明确指定,我认为可以安全地假设任何正在进行的项目都是 3.5+ . 67% of all .NET users are on version 4 and 26% are on some version of 3.
【解决方案3】:

我建议进行一些短路以使事情变得更简单,并在数组是相同引用 (a1 = b1) 的情况下使用 object.ReferenceEquals 进行短路:

public bool Equality(byte[] a1, byte[] b1)
{
    // If not same length, done
    if (a1.Length != b1.Length)
    {
        return false;
    }

    // If they are the same object, done
    if (object.ReferenceEquals(a1,b1))
    {
        return true;
    }

    // Loop all values and compare
    for (int i = 0; i < a1.Length; i++)
    {
        if (a1[i] != b1[i])
        {
            return false;
        }
    }

    // If we got here, equal
    return true;
}

【讨论】:

    【解决方案4】:

    这应该可行:

    public bool Equality(byte[] a1, byte[] b1)
    {
       if(a1 == null || b1 == null)
           return false;
       int length = a1.Length;
       if(b1.Length != length)
          return false;
       while(length >0) {
           length--;
           if(a1[length] != b1[length])
              return false;           
       }
       return true;        
    }
    

    【讨论】:

      【解决方案5】:

      你应该添加一些返回语句:

      public bool Equality(byte[] a1, byte[] b1)
      {
          int i = 0;
          if (a1.Length == b1.Length)
          {
              while ((i < a1.Length) && (a1[i]==b1[i]))
              {
                  i++;
              }
          }
          return i == a1.Length;
      }
      

      或者,更好

      public bool Equality(byte[] a1, byte[] b1)
      {
          if(a1.Length != b1.Length)
          {
              return false;
          }
      
          for (int i = 0; i < a1.Length; i++)
          {
              if (a1[i] != b1[i])
              {
                  return false;
              }
          }
          return true;
      }
      

      【讨论】:

      • 您的第二个答案可能会引发 IndexOutOfBounds 异常
      • 先做长度检查,比较便宜。
      • 第一个不起作用,因为如果 a1.Length == 0b1.Length &gt; 0
      猜你喜欢
      • 2020-05-24
      • 2017-01-23
      • 2020-05-05
      • 2020-02-12
      • 1970-01-01
      • 2023-04-04
      • 2013-02-25
      相关资源
      最近更新 更多