#!/usr/bin/env ruby # © 2002 Jos Backus # # 2002-01-22 Initial version # 2002-06-02 Updates inspired by comments by Jack Herrington # # This script is a reimplementation of most of the xxd utility that ships with # vim. It can create an editable text dump of a file, and (when the -r option # is specified) recreate a file based on a text dump. It sends its output to # stdout. # The dump line format looks like this: # 0000000: 7f45 4c46 0101 0109 0000 0000 0000 0000 .ELF............ $progname = File.basename($0) def usage STDERR.puts "usage: #$progname [-r] [file]" exit 64 end class Fixnum def even? self % 2 == 0 end def printable case self when 0..037, 0177..0377 then "." else self.chr end end end def printline(n, c, chars) i = 0 line = chars.map {|ch| i += 1; sprintf "%02x%s", ch, i.even? ? ' ' : '' } text = chars.map {|ch| ch.printable } printf "%07x: %-40s %-#{n}s\n", c - c % n, line, text end revert = nil while ARGV[0] =~ /^-/ case ARGV[0] when "-r" revert = 1 else STDERR.puts "#$progname: illegal option -- #{ARGV[0]}" usage end ARGV.shift end if revert $stdout.binmode # when running under DOS/Windows pat = /^[\da-f]{7}:(( [\da-f]{4}){1,8})/ while line = ARGF.gets if m = pat.match(line) print m[1].split(' ').map {|h| h.hex}.pack("n*") end end else n = 16 c = 0 chars = [] while ch = ARGF.getc chars << ch if (c += 1) % n == 0 printline(n, c - n, chars) chars.clear end end # Print remaining bytes, if any printline(n, c, chars) unless chars.empty? end exit