Generate md5 hash of JSON and compare in Python and JavaScript
Question:
I have a use case where i have to generate md5
hash of a JSON
object and compare the hashes in the server and the browser.
The browser client generates hash and then asks the server for the hash of the same resource[ which happens to be a JSON object], and compares both the hashes to decide what to do next.
For server i am using Python
and browser client is in Javascript
.
For me the hashes generated in both cases do not match. Here’s my code:
Python:
>>> import hashlib
>>> import json
>>> a = {"candidate" : 5, "data": 1}
>>> a = json.dumps(a, sort_keys = True).encode("utf-8")
>>> hashlib.md5(a).hexdigest()
>>> 12db79ee4a76db2f4fc48624140adc7e
JS:
I am using md5 for hashing in browser
> var hash = require("md5")
> var data = {"candidate":5, "data":1}
> data = JSON.stringify(data)
> md5(data)
> 92e99f0a99ad2a3b5e02f717a2fb83c2
What is it that i am doing wrong?
Answers:
You’re assuming that both languages generate JSON that looks identical.
>>> json.dumps({"candidate" : 5, "data": 1}, sort_keys=True)
'{"candidate": 5, "data": 1}'
js> JSON.stringify({"candidate" : 5, "data": 1})
"{"candidate":5,"data":1}"
Fortunately, they can.
>>> a = json.dumps({"candidate" : 5, "data": 1}, sort_keys=True, indent=2)
'{n "candidate": 5,n "data": 1n}'
js> var a = JSON.stringify({"candidate" : 5, "data": 1}, null, 2)
"{n "candidate": 5,n "data": 1n}"
And now the hashes would be same as well.
Python:
>>> hashlib.md5(a.encode("utf-8")).hexdigest()
>>> d77982d217ec5a9bcbad5be9bee93027
JS:
>>> md5(a)
>>> d77982d217ec5a9bcbad5be9bee93027
The difference is that json.dumps
applies some minor pretty-printing by default but JSON.stringify
does not, that’s why hashes are not the same.
Python:
>>> import json
>>> json.dumps({"candidate" : 5, "data": 1})
'{"candidate": 5, "data": 1}'
Javacript:
> JSON.stringify({"candidate" : 5, "data": 1})
'{"candidate":5,"data":1}'
But with some modification, we can generate the same hash. There are two ways for it:-
- Modifying
javascript JSON string
to make it equivalent to a python JSON string
.
Python:
>>> import json,hashlib
>>> a = json.dumps({"candidate" : 5, "data": 1}, sort_keys=True)
>>> hashlib.md5(a.encode("utf-8")).hexdigest()
'12db79ee4a76db2f4fc48624140adc7e'
Javacript:
> const Crypto = require("crypto-js")
undefined
> const a = JSON.stringify({"candidate" : 5, "data": 1}).replaceAll(":", ": ").replaceAll(",", ", ")
undefined
> Crypto.MD5(a).toString(Crypto.enc.Hex)
'12db79ee4a76db2f4fc48624140adc7e'
- Modifying
python JSON string
to make it equivalent to a javascript JSON string
.
Python:
>>> import json,hashlib
>>> a = json.dumps({"candidate" : 5, "data": 1}, separators=(',', ':'))
>>> hashlib.md5(a.encode("utf-8")).hexdigest()
'92e99f0a99ad2a3b5e02f717a2fb83c2'
Javacript:
> const Crypto = require("crypto-js")
undefined
> const a = JSON.stringify({"candidate" : 5, "data": 1})
undefined
> Crypto.MD5(a).toString(Crypto.enc.Hex)
'92e99f0a99ad2a3b5e02f717a2fb83c2'
Note:- To run javascript code, crypto-js npm pkg should be installed as same location where you started the node shell.
I have a use case where i have to generate md5
hash of a JSON
object and compare the hashes in the server and the browser.
The browser client generates hash and then asks the server for the hash of the same resource[ which happens to be a JSON object], and compares both the hashes to decide what to do next.
For server i am using Python
and browser client is in Javascript
.
For me the hashes generated in both cases do not match. Here’s my code:
Python:
>>> import hashlib
>>> import json
>>> a = {"candidate" : 5, "data": 1}
>>> a = json.dumps(a, sort_keys = True).encode("utf-8")
>>> hashlib.md5(a).hexdigest()
>>> 12db79ee4a76db2f4fc48624140adc7e
JS:
I am using md5 for hashing in browser
> var hash = require("md5")
> var data = {"candidate":5, "data":1}
> data = JSON.stringify(data)
> md5(data)
> 92e99f0a99ad2a3b5e02f717a2fb83c2
What is it that i am doing wrong?
You’re assuming that both languages generate JSON that looks identical.
>>> json.dumps({"candidate" : 5, "data": 1}, sort_keys=True)
'{"candidate": 5, "data": 1}'
js> JSON.stringify({"candidate" : 5, "data": 1})
"{"candidate":5,"data":1}"
Fortunately, they can.
>>> a = json.dumps({"candidate" : 5, "data": 1}, sort_keys=True, indent=2)
'{n "candidate": 5,n "data": 1n}'
js> var a = JSON.stringify({"candidate" : 5, "data": 1}, null, 2)
"{n "candidate": 5,n "data": 1n}"
And now the hashes would be same as well.
Python:
>>> hashlib.md5(a.encode("utf-8")).hexdigest()
>>> d77982d217ec5a9bcbad5be9bee93027
JS:
>>> md5(a)
>>> d77982d217ec5a9bcbad5be9bee93027
The difference is that json.dumps
applies some minor pretty-printing by default but JSON.stringify
does not, that’s why hashes are not the same.
Python:
>>> import json
>>> json.dumps({"candidate" : 5, "data": 1})
'{"candidate": 5, "data": 1}'
Javacript:
> JSON.stringify({"candidate" : 5, "data": 1})
'{"candidate":5,"data":1}'
But with some modification, we can generate the same hash. There are two ways for it:-
- Modifying
javascript JSON string
to make it equivalent to apython JSON string
.
Python:>>> import json,hashlib >>> a = json.dumps({"candidate" : 5, "data": 1}, sort_keys=True) >>> hashlib.md5(a.encode("utf-8")).hexdigest() '12db79ee4a76db2f4fc48624140adc7e'
Javacript:
> const Crypto = require("crypto-js") undefined > const a = JSON.stringify({"candidate" : 5, "data": 1}).replaceAll(":", ": ").replaceAll(",", ", ") undefined > Crypto.MD5(a).toString(Crypto.enc.Hex) '12db79ee4a76db2f4fc48624140adc7e'
- Modifying
python JSON string
to make it equivalent to ajavascript JSON string
.
Python:>>> import json,hashlib >>> a = json.dumps({"candidate" : 5, "data": 1}, separators=(',', ':')) >>> hashlib.md5(a.encode("utf-8")).hexdigest() '92e99f0a99ad2a3b5e02f717a2fb83c2'
Javacript:
> const Crypto = require("crypto-js") undefined > const a = JSON.stringify({"candidate" : 5, "data": 1}) undefined > Crypto.MD5(a).toString(Crypto.enc.Hex) '92e99f0a99ad2a3b5e02f717a2fb83c2'
Note:- To run javascript code, crypto-js npm pkg should be installed as same location where you started the node shell.