Code Smell 167 - Hashing Comparison

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

  1. 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

Equality and Hash

Hashcode in Java

Hashcode vs Equal

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.