class Hexy def self.dump bytes, config={} Hexy.new(bytes, config).to_s end # # Constructor is passed the bytes to format as a hex dump and # an optinal configuration hash. Configuration parameters are: # # [:+width+] how many bytes per line (default: 16) # [:+numbering+] currently the only supported options are :hex_bytes and :none. Default is :hex_bytes # [:+format+] currently supported are :+twos+ (every two hex digits are separated by a space, default), :+fours+ or :+none+ # [:+case+] :+upper+ or :+lower+, default :+lower+ # [:+annotate+] :+ascii+ or :+none+, default :+ascii+ # [:+prefix+] a prefix to include literally in front of each line, default "" # [:+indent+] number of spaces to prefix in front of each line, default 0 # # # # # # ==Examples # (Width = 16, Line Numbers = :hex_bytes, Format = :twos) # 0000000: 00 01 03 05 1f 0a 09 62 63 64 65 66 67 68 69 6a .......b cdefghij # 0000010: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a klmnopqr stuvwxyz # 0000020: 30 31 32 33 34 35 36 37 38 39 01234567 89 # # (Width = 16, Line Numbers = :none, Format = :fours) # 0001 0305 1f0a 0962 6364 6566 6768 696a .......b cdefghij # 6b6c 6d6e 6f70 7172 7374 7576 7778 797a klmnopqr stuvwxyz # 3031 3233 3435 3637 3839 01234567 89 # # ==Usage # # The examples above were generated with the following: # # b = Hexy.new "\x00\x01\x03(...)" # puts p.to_s # # b = Hexy.new "\x00\x01\x03(...)", :numbering=>:none, :format=>:fours # puts p.to_s # def initialize bytes, config = {} @bytes = bytes @width = config[:width] || 16 @numbering = config[:numbering] == :none ? :none : :hex_bytes @format = case config[:format] when :none, :fours config[:format] else :twos end @case = config[:case] == :upper ? :upper: :lower @annotate = config[:annotate] == :none ? :none : :ascii @prefix = config[:prefix] ||= "" @indent = config[:indent] ||= 0 1.upto(@indent) {@prefix += " "} end def to_s str = "" 0.step(@bytes.length, @width) {|i| string = @bytes[i,@width] hex = string.unpack("H*")[0] hex.upcase! if @case == :upper if @format == :fours hex.gsub!(/(.{4})/) {|m| m+" " } elsif @format == :twos hex.sub!(/(.{#{@width}})/) { |m| m+" " } hex.gsub!(/(\S\S)/) { |m| m+" " } end string.gsub!(/[\000-\040\177-\377]/, ".") string.gsub!(/(.{#{@width/2}})/) { |m| m+" " } len = case @format when :fours (@width*2)+(@width/2) when :twos (@width * 3)+2 else @width *2 end str << @prefix str << "%07X: " % (i) if @numbering == :hex_bytes str << ("%-#{len}s" % hex) str << " #{string}" if @annotate == :ascii str << "\n" } str << "\n" end end if $0 == __FILE__ b = Hexy.new "abc" puts b.to_s b = Hexy.new "\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789" puts b.to_s b = Hexy.new "\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :format=>:none puts b.to_s b = Hexy.new "\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :annotate=>:none puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:none, :format=>:fours) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:none, :format=>:fours, :case=>:upper) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :format=>:fours) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:none, :width=>8) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:hex_bytes, :width=> 8) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:hex_bytes, :width=> 8, :format=>:fours) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:none, :width=>32) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:hex_bytes, :width=>32) puts b.to_s b = Hexy.new("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789", :numbering=>:hex_bytes, :width=>32, :format=>:fours) puts b.to_s end