Showing posts with label Hash. Show all posts
Showing posts with label Hash. Show all posts

Wednesday, 15 August 2012

Pojomatic for Equals(), HashCode() and toString()

From the website itself: "Pojomatic provides configurable implementations of the equals(Object), hashCode() and toString() methods inherited from java.lang.Object"

This is best described with an example (available on Github, in the Introduction-To-Pojomatic directory):
@AutoProperty
public class Item {

    @Property(policy=PojomaticPolicy.EQUALS_TO_STRING)
    private long id = 0;

    private String description = "";

    @Property(policy=PojomaticPolicy.NONE)
    private transient int transientData;

    @Override
    public boolean equals(Object o) {
        return Pojomatic.equals(this, o);
    }

    @Override
    public int hashCode() {
        return Pojomatic.hashCode(this);
    }

    @Override
    public String toString() { 
        return Pojomatic.toString(this);
    }

    // Constructors, Setters & Getters...

}
Notice that equals(), hashCode() and toString() are overriden to call Pojomatic.

The @AutoProperty annotation enables Pojomatic on an class. It has two optional properties:
  • The auto detect policy indicates whether FIELDs or METHODs should be searched for properties to take into account. The search can also be disabled with NONE. By default, the FIELDs are searched for.
  • The default Pojomatic policy which indicates whether the properties are going to be included in equals(), hashCode() and toString(). By default, the policy is set to ALL. Other values are: EQUALS, EQUALS_TO_STRING, HASHCODE_EQUALS, NONE, TO_STRING.
The class level configuration can also be overridden at the field (or method) level with the @Property annotation. It also has two properties:
  • The name, which identifies the property in toString().
  • The policy, which is very similar to the default Pojomatic policy, but at the field/method level. It can take the same values, plus one: DEFAULT, which means 'the class level policy' (or ALL if none is defined).
The following:
Item item = new Item();
item.setDescription("Blue furniture");
item.setId(123456);
item.setTransientData(9999);

System.out.println("equals   : " + item.equals(new Object()));
System.out.println("hashCode : " + item.hashCode());
System.out.println("toString : " + item.toString());
Generates the following output:
equals   : false
hashCode : -2089463829
toString : Item{id: {123456}, description: {Blue furniture}}
Pojomatic also offers:
  • a feature to control formatting in toString()
  • a mean to prevent a subclass from overridding equals()
  • Assuming B extends A, but you don't want an instance of B to be equal to an instance of A ever, there is a mean to notify Pojomatic
  • Assuming B extends A, and you would like to retrieve the difference in terms of properties used to compute equals(), Pojomatic.diff(...) provides this information
  • One can retrieve the Pojomator used to compute equals(), hashCode() and toString(); it also contains an interesting isCompatibleForEquality() method to check whether another class can be used in equals()

Friday, 10 August 2012

How to Digest (or Hash) data with MD5, SHA1, SHA256 in Java?

Java offers a functionality to compute/hash/digest messages. The available algorithms are: MD2, MD5, SHA-1, SHA-256, SHA-384 or SHA-512:
public static void main(String[] args)
        throws NoSuchAlgorithmException {

    byte[] ba = { 120, 35, 48, -33, -99, -10 };

    System.out.println("MD2     :"
        + Hex.encodeHexString(digest(ba, "MD2")));
 
    System.out.println("MD5     :"
        + Hex.encodeHexString(digest(ba, "MD5")));

    System.out.println("SHA-1   :"
        + Hex.encodeHexString(digest(ba, "SHA-1")));

    System.out.println("SHA-256 :"
        + Hex.encodeHexString(digest(ba, "SHA-256")));

    System.out.println("SHA-384 :"
        + Hex.encodeHexString(digest(ba, "SHA-384")));

    System.out.println("SHA-512 :"
        + Hex.encodeHexString(digest(ba, "SHA-512")));

}

public static byte[] digest(byte[] ba, String algorithm)
        throws NoSuchAlgorithmException {

    return MessageDigest.getInstance(algorithm).digest(ba);

}
We use the Hex class to convert byte arrays into hexadecimal strings. The generated output is:
MD2     :47493b5943a77cbd2d8a6d3907b3d215
MD5     :ce4f085c5bd8ecdc26a1b9ec94b8d081
SHA-1   :2a0d7f604439952d92b122fd872eee9bbb46b2d5
SHA-256 :de416f208796b60f0f2f1e17b3d0b1273580c29f71dac50fb8db46d1ed77c6c1
SHA-384 :439f5f0697c1dce75d4599e9256f1a4c11886846fc0cc342f5f8e3d70e5bb2890032c6dd359825ef267832266c6d09cd
SHA-512 :3b73aaec89f98bbb149380134036fcd6fdc4b18e59cad0bf6be704cd432de35c2dfb8f3901b8f1d6324bf53930b7f410b62db51beaab2e6959b98b3f53a28493

More Java tips & tricks here.