On 7/28/08, Martin Boese <boesemar / gmx.de> wrote: > On Sunday 27 July 2008 22:51:04 Mikael Høélund wrote: > > Oh hi, I just thought I'd golf a solution. I'm sure other people can > > do a much better job than I making a full hexdumping suite, so I just > > had some fun. Can't seem to get it lower than 78 characters, > > unfortunately. > > > > I added an ascii column to your solution... now it's about twice the size-) > > i = 0 > $<.read.scan(/.{0,16}/m) { > puts(("%08x " % i) + $&.unpack('H4'*8).join(' ') + ' ['+ > $&.split(//).collect { |c| c.inspect[1] == 92 ? '.' :c }.join +]' ) > i += 16 > } > I can't resist golf: I got Martin's solution down to 95 bytes (If you take out the ascii column it's down to 71). i=0;$<.read.scan(/.{0,16}/m){puts"%08x0 "%i+$&.unpack('H4'*8)*' '+' | '+$&.tr('^ -~','.');i+=1} Tricks: *' ' is a shorter version of .join(' ') for arrays, and $&.tr('^ -~','.') says translate any character not between ' ' and '~' (32 to 126) to a '.' That saved a ton over the split/collect/inspect method. (By the way, map and dump save a few bytes over collect and inspect) I also did a more full-featured version that supports some command line options -Adam ---------------------------------------------------- #hexdump utility for RubyQuiz#171 USAGE=<<USAGE Usage: #{$0.split(/[\/\\]/)[-1]} [-n length] [-s skip] [-g group] [-w width] [-a] file Dumps <length> bytes of <file> in hex format, starting at offset <skip>. Prints <width> bytes per line in groups of size <group>. Prints the ascii on the right unless <-a> specified Default is all bytes of $stdin in 16/2 format. USAGE begin width=16 group=2 skip=0 length=Float::MAX do_ascii = true file = $stdin while (opt=ARGV.shift) if opt[0]==?- case opt[1] when ?n length=ARGV.shift.to_i when ?s skip=ARGV.shift.to_i when ?g group = ARGV.shift.to_i when ?w width = ARGV.shift.to_i when ?a do_ascii = false else raise ArgumentError,"invalid Option #{opt}" end else file = File.new(opt) end end n=0 ascii='' file.read(skip) file.each_byte{|b| if n%width == 0 print "%s\n%08x "%[ascii,n+skip] ascii='| ' if do_ascii end print "%02x"%b print ' ' if (n+=1)%group==0 ascii << "%s"%b.chr.tr('^ -~','.') if do_ascii break if n>length } puts ' '*(((2+width-ascii.size)*(2*group+1))/group.to_f).ceil+ascii #this is probably the most complicated line #it pads out the line to get the remaining ascii to align: # (2+width-ascii.size) is the number of bytes missing (the 2 is for the ') # *(2*group+1) is the width of a group of bytes with the space # /group.to_f divides by the number of groups # .ceil rounds up, otherwise we misalign on partial groups rescue =>x puts USAGE, "ERROR: #{x}" end