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