Skip to content

Instantly share code, notes, and snippets.

@atamurad
Created October 12, 2011 19:23
Show Gist options
  • Save atamurad/1282243 to your computer and use it in GitHub Desktop.
Save atamurad/1282243 to your computer and use it in GitHub Desktop.
Recurly.js signature implementation in Python
import hashlib
import hmac
def digest_data(data):
if type(data) == list:
return "[%s]" % (",".join([digest_data(v) for v in data if v]))
elif type(data) == dict:
kvs = sorted(data.items(), lambda x,y: cmp(x[0],y[0]))
def prefix(key):
return "" if type(key) == int else "%s:" % key
kvs = ["%s%s" % (prefix(item[0]), digest_data(item[1])) for item in kvs if item[1]]
return "[%s]" % ",".join(kvs)
elif type(data) == str or type(data) == unicode:
return "".join(map(lambda x: "\\"+x if x in "\\[]:," else x, data))
else:
return str(data)
def generate_signature(claim, args, timestamp, private_key):
key = hashlib.sha1(private_key).digest()
msg = digest_data([timestamp,claim,args])
h = hmac.new(key, digestmod=hashlib.sha1)
h.update(msg)
return h.hexdigest() + "-" + str(timestamp)
test_sig = 'fb5194a51aa97996cdb995a89064764c5c1bfd93-1312806801'
key = "0123456789abcdef0123456789abcdef"
args = {"a":"foo", "b":"bar"}
assert generate_signature("update", args, 1312806801, key) == test_sig
assert digest_data({"a":1, "c":3, "b":2}) == '[a:1,b:2,c:3]'
assert digest_data({1:4, 2:5, 3:6}) == '[4,5,6]'
assert digest_data({"a":[1,2,3], "b":{"c": '123', "d":'456'}}) == '[a:[1,2,3],b:[c:123,d:456]]'
assert digest_data([[], {}, '', None]) == '[]'
assert digest_data({"syntaxchars":' \\ [ ] : , '}) == '[syntaxchars: \\\\ \[ \] \: \, ]'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment