Skip to content

Instantly share code, notes, and snippets.

@APTy
Last active November 20, 2017 15:44
Show Gist options
  • Save APTy/8dea3010c0b261689339a8cc52e8dc76 to your computer and use it in GitHub Desktop.
Save APTy/8dea3010c0b261689339a8cc52e8dc76 to your computer and use it in GitHub Desktop.
base64-json-decoder

base64-json-decoder

Quickstart

Install

pip install -e git+https://gist.github.com/APTy/8dea3010c0b261689339a8cc52e8dc76#egg=base64-json-decoder

This installs: base64-json-decoder, aliased as bjd.

Usage

Decode JSON data with arbitrarily nested base64+JSON within:

$ echo '{"payload":"eyJtZXNzYWdlIjoiSGVsbG8hIiwgImZyb20iOiAiQVBUeSJ9Cg=="}' | bjd
{
  "payload": {
    "message": "Hello!", 
    "from": "APTy"
  }
}

It will even try to turn timestamps into something more readable:

$ echo '{"occurred_at": 1500000000}' | bjd
{
  "occurred_at": "2017-07-13 19:40:00 UTC"
}
import json
import base64
import datetime
import fileinput
def main():
"""Reads nested base64/json input and prints the decoded version."""
in_bytes = _get_input()
out = _decode_all(in_bytes)
_print_output(out)
def _get_input():
"""Get user input from stdin or from filenames passed as args."""
inputs = []
for line in fileinput.input():
inputs.append(line)
return ''.join(inputs)
def _decode_all(in_bytes):
"""Decode the nested base64/json combination payload."""
# attempt to decode the input string
out = _try_decode(in_bytes)
# if this isn't nested further, return the value
if type(out) != dict:
return out
# loop over every nested item and try to decode it
for key, val in out.items():
# if this value isn't nested further, decode it
if type(val) != dict:
out[key] = _decode_all(val)
continue
# if this value is nested further, recursively decode its contents
for nestedKey, nestedVal in val.items():
val[nestedKey] = _decode_all(nestedVal)
return out
def _try_decode(in_bytes):
"""Attempts to decode using a variety of different methods.
Returns the input value if decoding fails.
"""
# try plain json decode
try:
return json.loads(in_bytes)
except:
pass
# try base64+json decode
next_bytes = None
try:
next_bytes = base64.b64decode(in_bytes)
except:
next_bytes = in_bytes
try:
return json.loads(next_bytes)
except:
pass
# try timestamp decode
try:
return _convert_ts(in_bytes)
except:
pass
# if every decode has failed, return the original value
return in_bytes
def _convert_ts(ts):
"""Attempt to convert a value that looks like a timestamp into a readable form."""
return datetime.datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S UTC")
def _print_output(out):
"""Pretty-print output to terminal."""
print(json.dumps(out, indent=2))
if __name__ == "__main__":
main()
from setuptools import setup, find_packages
setup(
name="base64-json-decoder",
version="0.1.0",
description="CLI for decoding nested base64-json",
packages=find_packages(),
entry_points={"console_scripts": [
"base64-json-decoder=main:main",
"bjd=main:main",
]}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment