#!/usr/bin/env python # Display a binary (or any) file in chars (if printable), hex and decimal. # Similar to what od -xc used to do before GNU got hold of it, # or what xxd (part of the vim package) does, # but (IMO) with cleaner and more readable output. # Copyright 2009 by Akkana Peck. Share and enjoy under the GPL v2 or later. import sys, os import curses.ascii do_char = False do_hex = False do_dec = False file_list = [] multi_format = False def Usage() : print "Usage:", os.path.basename(sys.argv[0]), "[-cxd] file ..." exit(1) def parse_opts() : global do_char, do_hex, do_dec, file_list, multi_format num_formats = 0 for i in range(1, len(sys.argv)) : if sys.argv[i][0] != '-' : file_list = sys.argv[i:] break for c in sys.argv[i][1:] : if c == 'c' : do_char = True num_formats = num_formats + 1 elif c == 'x' : do_hex = True num_formats = num_formats + 1 elif c == 'd' : do_dec = True num_formats = num_formats + 1 elif c == 'h' : Usage() if num_formats == 0 : do_char = True do_hex = True do_dec = True num_formats = 3 if num_formats > 1 : multi_format = True def bdump(filename, do_char, do_hex, do_dec) : if len(file_list) > 1 : print filename + ":" if filename : try : fp = open(filename, "r") except IOError, e: print "Can't open", filename, ":\n ", e #sys.exit(e.errno) return else : fp = sys.stdin try : while True : line = fp.read(16) if line == "" : break if do_char : for c in line : if curses.ascii.isprint(c) : print "%4c" % (c), elif curses.ascii.iscntrl(c) : print " ^" + chr(ord(c) + ord('A') - 1), else : print ' ', print if do_hex : for c in line : print "%4x" % (ord(c)), print if do_dec : for c in line : print "%4d" % (ord(c)), print if multi_format : print except IOError, e : if e.errno == 32 : # Broken pipe sys.exit(0) print e sys.exit(e) fp.close() # main() : parse_opts() if len(file_list) == 0 : bdump(None, do_char, do_hex, do_dec) else : for filename in file_list : bdump(filename, do_char, do_hex, do_dec)