Code Smell 167 - Hashing Comparison
Hashing guarantees two objects are different. Not that they are the same
TL;DR: If you check for the hash, you should also check for equality
Problems
Solutions
- Check for hash (fast) and then check for Equality (slow)
Context
On 2022 Oct 7th one of the larger blockchains had to be halted.
This news was shocking since most blockchains are decentralized by definition.
You can read a full article here:
Sample Code
Wrong
public class Person {
public String name;
// Public attributes are another smell
@Override
public boolean equals(Person anotherPerson) {
return name.equals(anotherPerson.name);
}
@Override
public int hashCode() {
return (int)(Math.random()*256);
}
// This is just an example of non-correlation
// When using HashMaps we can make a mistake
// and guess the object is not present in the collection
}
Right
public class Person {
public String name;
// Public attributes are another smell
@Override
public boolean equals(Person anotherPerson) {
return name.equals(anotherPerson.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
// This is just an example of non-correlation
}
Detection
[X] Semi-Automatic
Many linters have rules for hash and equality redefinition.
With mutation testing, we can seed different objects with the same hash and check our tests.
Identity
Security
Conclusion
Every performance improvement has its drawbacks.
Caches and replications are notable examples.
We can (must) use them carefully.
Relations
More Info
Disclaimer
Code Smells are just my opinion.
This will surprise some of your readers, but my primary interest is not with computer security. I am primarily interested in writing software that works as intended.
Wietse Venema
This article is part of the CodeSmell Series.