mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
130 lines
3.2 KiB
Python
Executable File
130 lines
3.2 KiB
Python
Executable File
#!/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 <file>' % ProgName
|
|
print 'where <file> 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))
|