#!/usr/bin/env python """ File octal dump program. Tool used developinf pymlac. """ import sys import getopt import os.path OCTLEN = 55 CHARLEN = 16 def octaldump(filename): """A function that generates an 'octal dump' of a file. Calling this function for a file containing 'The quick brown fox\n\tjumps over the lazy dog.' returns a string containing: 0000000 000001 002003 004005 006007 010011 012013 014015 016017 |The quick brown | 0000010 020021 022023 024025 026027 030031 032033 034035 036037 |fox..jumps over | 0000020 040041 042043 044045 046047 050051 052053 054055 |the lazy dog.| +---------+---------+---------+---------+---------+---------+---------+---------+---------+-- 0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 Each line of the dump contains info about 16 bytes or less of the input string. The 7 octal digits starting at column 0 are the offset of the first word of the line from the start of the file. The 8 octal words starting at column 9 and ending at column 63 are the 8 word values in octal. The characters spanning columns 61-82 are the 16 printable characters. If a character is not printable it is replaced by a '.' character. """ with open(filename, 'rb', 8192) as f: offset = 0 while True: data = f.read(16) if len(data) == 0: break try: print(octaldump_line(data, offset)) except IOError: return offset += 8 def octaldump_line(s, offset): """Generate one line of fdump output. s string to convert (16 bytes or less) offset offset from start of dump """ oct = '' char = '' # iterate over string 2 chars at a time for (high, low) in zip(s[0::2], s[1::2]): high_ord = ord(high) low_ord = ord(low) value = (high_ord << 8) + low_ord oct += '%07o ' % value if ord(' ') <= high_ord <= ord('~'): char += high else: char += '.' if ord(' ') <= low_ord <= ord('~'): char += low else: char += '.' oct = (oct + ' '*OCTLEN)[:OCTLEN] char = (char + '|' + ' '*CHARLEN)[:CHARLEN+1] return '%07o %s |%s' % (offset, oct, char) ################################################################################ ProgName = None def usage(): print 'usage: %s ' % ProgName print 'where is the file to produce the octaldump of.' def main(argv): global ProgName ProgName = os.path.basename(argv[0]) try: opts, args = getopt.gnu_getopt(argv, "h", ["help"]) except getopt.GetoptError: usage() return 10 for opt, arg in opts: if opt in ("-h", "--help"): usage() return 0 if len(args) != 2: usage() return 10 filename = args[1] try: f = open(filename) except IOError: print "Sorry, can't find file '%s'" % filename return 10 f.close() octaldump(filename) if __name__ == "__main__": sys.exit(main(sys.argv))