UNMENTIONABLES = Range.new(0, 255).select {|ord| ord < 32 || ord > 126 }.map {|ord| ord.chr }.join def hexdump(block) # Format: <address> <8 bytes> <8 bytes> |<16 chars>| result = "" count = (block.length / 16).to_i slack = (block.length % 16).to_i Range.new(0, count - 1).each {|index| offset = index * 16 sample = block[offset, 16] fmt = "%08x " + ("%02x " * 8) + " " + ("%02x " * 8) + " |%s|\n" args = [] args << (offset % 0x100000000) sample.each_byte {|byte| args << byte } args << sample.tr(UNMENTIONABLES, '.') result += sprintf(fmt, *args) } # Handle slack if slack > 0 offset = count * 16 sample = block[offset, slack] fmt = "%08x " if slack >= 8 fmt += ("%02x " * 8) + " " end fmt += ("%02x " * (slack % 8)) + " " args = [] args << (offset % 0x100000000) sample.each_byte {|byte| args << byte } tmp = sprintf(fmt, *args) tmp += " " * (60 - tmp.length) if tmp.length < 60 tmp += sprintf("|%s|\n", sample.tr(UNMENTIONABLES, '.')) result += tmp end result end