487 votos

Comparación de matrices de dos bytes en .NET

¿Cómo puedo hacer esto? Claro que puedo hacer esto:

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

Pero tampoco busco una función BCL o algunos altamente optimizan manera probada para ello.

[Editar]Gracias a JasonBunting y aku para su entrada.

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

funciona muy bien, pero no parece que trabajaría para x 64.

[Editar] Tenga en cuenta mi respuesta súper rápido aquí.

563voto

aku Puntos 54867

Puede utilizar el método de 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

Si no puede utilizar .NET 3.5 por alguna razón, su método está bien.
Entorno de tiempo de Compiler\run optimizará su bucle así no tienes que preocuparte por rendimiento.

229voto

plinth Puntos 26817

P/Invoke potencias activa!

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

154voto

Ohad Schneider Puntos 10485

Hay una nueva solución integrada para esto en .NET 4 - IStructuralEquatable

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

70voto

Hafthor Puntos 5663

ebil gil sugirió código inseguro que dio lugar a esta solución:

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

el que hace de 64 bits basado en la comparación tanto de la matriz como sea posible. Esta un poco en cuenta el hecho de que las matrices de inicio qword alineados. Va a funcionar si no qword alineados, solo que no tan rápido como si lo fuera.



Se realiza aproximadamente 7 veces más rápido que el simple bucle for. Uso de la J# biblioteca realiza de forma equivalente a la original para el bucle. El uso de .SequenceEqual corre alrededor de 7 veces más lento, creo que sólo porque es el uso de IEnumerator.MoveNext. Me imagino que LINQ soluciones basadas en por lo menos el que lento o peor.

25voto

Jason Bunting Puntos 27534

Si no se opone a hacerlo, puede importar la Asamblea J# "vjslib.dll" y utilizar su Arrays.equals (byte [], método byte[])...

No me culpes si alguien se ríe de ti...


Editar: Para lo poco que valga, solía Reflector para desensamblar el código para eso, y aquí es lo que parece:

public static bool equals(sbyte[] a1, sbyte[] a2)
{
  if (a1 == a2)
  {
    return true;
  }
  if ((a1 != null) && (a2 != null))
  {
    if (a1.Length != a2.Length)
    {
      return false;
    }
    for (int i = 0; i < a1.Length; i++)
    {
      if (a1[i] != a2[i])
      {
        return false;
      }
    }
    return true;
  }
  return false;
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X