1
int equal = 0;
for (int i = 0; i < a.length(); i++) {
   equal |= a.charAt(i) ^ b.charAt(i);
}
return equal == 0;

I understand pipe and XOR operator But what is |= doing?

DwB
  • 37,124
  • 11
  • 56
  • 82
titogeo
  • 2,156
  • 2
  • 24
  • 41

3 Answers3

5

It is similar to +=. See the table here

|=        bitwise inclusive OR and assignment operator   C |= 2 is same as C = C | 2

So it is equivalent to writing your code as:

equal = equal | a.charAt(i) ^ b.charAt(i)

Also as luk2302 has pointed out correctly, that there (bitwise exclusive OR)^ has higher precedence over (bitwise inclusive OR)| so you can include it inside the brackets like this:

equal = equal | (a.charAt(i) ^ b.charAt(i))
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • 3
    *Additional note*: note that `^` gets evaluated before `|` and therefore the statements are actually identical. If you are not sure what the [operator precedence](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html) of those binary operators is I would recommend adding `()` around it like `equal = equal | (a.charAt(i) ^ b.charAt(i))` to make it understandable for everyone. – luk2302 Dec 31 '15 at 13:08
  • @luk2302:- Bringing down the point of operator precedence is very informative for this example. +1 – Rahul Tripathi Dec 31 '15 at 13:09
2

Diatribe

This code is appears to be a great example of why goofballs should not be hired as programmers.

Answer

Here is an explanation of the code:

  1. Start with two strings, which are presumed to be the same length.
  2. Perform an xor operation on two characters.
  3. "Add" the result of the xor operation to an accumulator (named equal; as an aside, in context I prefer the even less obvious variable name artificialSweetener) using the or-equals operator.
  4. If not at the end of string a, repeat starting at step 2 above.
  5. If, after the loop completes, the value of the equal (or artificialSweetener as you wish) operator is zero, then return true. Else return false.

Notes

The or-equals operator performs a bitwise or operation between the left hand argument and the right hand argument then assigns the result to the left hand argument. This means that this statement:

left |= right

performs the same work as this statement:

left = (left | right)

Why the Anger

It is common for goofballs to regularly reinvent already existing functionality and to do it poorly. In this sense, the code above is a success; it both reinvents existing functionality and does it terribly.

This code exhibits some disturbingly incompetent behaviour

  1. It continues performing comparison even after a difference has been found.
  2. It will throw value-free NullPointerExceptions if a and/or b are null.
  3. It has the benefit of being not at all obvious to a newer java programmer.
  4. It throws an exception if string b is shorter in length than string a.
  5. It returns a false positive when string a is an initial subset of string b. For example, a = "Blah" and b = "BlahNotAtAllEqual" will result in a false positive.

What would a competent programmer do

A programmer who is not an idiot would perform a string comparison operation using the String.equals method or, if they are more than just barely competent, they would use a utility like the Apache Commons Lang StringUtils to perform null safe comparisons.

DwB
  • 37,124
  • 11
  • 56
  • 82
  • Oh, no. Point 2, 4 was taken care before the fragment. This code is from [JHipster](https://github.com/jhipster/generator-jhipster/blob/master/app/templates/src/main/java/package/security/xauth/_TokenProvider.java) method constantTimeEquals – titogeo Dec 31 '15 at 14:49
  • 1
    There's nothing wrong with having preconditions, and 1 is a requirement as it turns out. The "competent" thing is wrong, in context. Not everything that looks like a weird trick is necessarily wrong. – harold Dec 31 '15 at 16:20
0

It's simple mate. The following lines do the same thing:

equal |= a.charAt(i) ^ b.charAt(i);
equal = equal | (a.charAt(i) ^ b.charAt(i));
vlence
  • 405
  • 4
  • 8