36

I am checking the equality of two byte arrays, and I wanted some help because what I have returns false even though the arrays should be equal.

Within my debug I could see both of a1 and b1 are equal, but it is not going inside the while loop to increment 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; } 

This always returns false: (a1[i]==b1[i]).

7
  • 5
    Where is your return statement? Commented Aug 27, 2013 at 18:28
  • Is hashB supposed to be b1? Commented Aug 27, 2013 at 18:28
  • as far as i can tell it doesn't return anything Commented Aug 27, 2013 at 18:29
  • Which framework version? Commented Aug 27, 2013 at 18:36
  • 3
    You cannot keep changing the question this much after we answer it, all the responses are going to be confused between different versions of the question. Post it as a new question... Commented Aug 27, 2013 at 18:51

5 Answers 5

63

You need to add a return value somewhere. This should work:

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

But this is much simpler:

return a1.SequenceEqual(b1); 

Alternatively, you could use IStructuralEquatable from .NET 4:

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

If performance is a concern, I'd recommend rewriting your code to use the Binary class, which is specifically optimized for this kind of use case:

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

A quick benchmark on my machine gives the following stats:

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 

Download this LINQPad file to run the benchmark yourself.

Sign up to request clarification or add additional context in comments.

9 Comments

i am using this to compare two different files and return the difference ( what records were added or removed) not that it runs and loops properly i am not getting a returned message about the difference of the files in which one file had records removed
@Masriyah So what you really want to do is implement a diff algorithm? That's an entirely different task than simply checking equality. I recommend you look at Google's diff-match-patch library.
I went ahead and uploaded the other parts of my code which is relating to this. Maybe you can take a look and point something out. i've been running around in circles with this all day. thanks
Logically there is no difference between OP's code and this code as far as first solution is concerned. OP only forgot to initialize bEqual to false which if done would also yield the same result.
i posted a new question if you can take a look. stackoverflow.com/questions/18473580/…
|
44

To check equality you can just write:

var areEqual = a1.SequenceEqual(b1); 

4 Comments

That technically requires LINQ which might not match his framework
But if it does match his framework it is a much better way of doing it.
@Moop Linq has been around for 6 years now, surely most people have upgraded to at least framework 3.5 by now.
@MikePrecup in this day an age, unless explicitly specified, I think it is safe to assume that any project being worked on is 3.5+. 67% of all .NET users are on version 4 and 26% are on some version of 3.
6

I'd recommend some short-circuiting to make things a bit simpler, and use of object.ReferenceEquals to short-circuit for cases when the arrays are the same reference (a1 = b1):

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

Comments

1

This should work:

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

Comments

0

You should add some return statements:

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

Or, better yet

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

3 Comments

You second answer might throw an IndexOutOfBounds exception
Do the length check first, it is less expensive.
The first won't work because if a1.Length == 0 and b1.Length > 0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.