Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hashing a Java JSONObject

Tags:

java

I'm currently writing a jsonrpc-client in java. A request is represented by an JSONObject like this:

{'method': 'do.stuff', 'params': ['asdf', 3, {'foo': 'bar'}]}

Now I want to implement a low-level request cache and for this I need a way to create a hash from a JSONObject that will always return the same value. Using the toString() is not an option since JSONObjects are unordered: the following example would do exactly the same as my first example even though the string representation is different:

{'params': ['asdf', 3, {'foo': 'bar'}], 'method': 'do.stuff'}

Whats the best solution to this problem? The jsonobject may be nested to any arbitrary depth of course. I'm fairly new to Java and thankful for any suggestion.

like image 396
oli Avatar asked Jul 19 '26 10:07

oli


2 Answers

You want to have a look at Jackson: read your input as a JsonNode, which implements .equals() and .hashCode() correctly (that is, sticking to the contract established by java.lang.Object), for all JSON values (numbers, booleans, strings, objects recursively, arrays recursively, nulls).

like image 103
fge Avatar answered Jul 20 '26 22:07

fge


I agree with @fge's solution. This is working for me across multiple variations of a JSON structure -

    int hash = 0;
    ObjectMapper mapper = new ObjectMapper();
    JsonFactory factory = mapper.getFactory();
    try {
        JsonNode jsonNode = mapper.readTree(factory.createParser(jsonString));
        hash = jsonNode.hashCode();
    } catch (IOException e) {
        LOG.error("Error generating hash for jsonString: {}", jsonString);
        e.printStackTrace();
    }


Example permutations - 
 "{ k1: v1, k2:v2, k3: v3}"
 "{ k3: v3, k2:v2, k1: v1}"
 "{ k3: v3, k1:v1, k2: v2}"

All 3 produced same hashcode everytime. In practice however my json also had ArrayList and Map within itself and that worked perfectly well too.

like image 23
user2756335 Avatar answered Jul 21 '26 00:07

user2756335



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!