もりきゅうです。

Koji Arai <JCA02266 / nifty.ne.jp> wrote:
> ・同じ行の出力は省略したい
> ・日本語出力に対応したい

これらについて考えてみました。


・同じ行の出力は省略したい

「行」というのは raw のことでしょうか? 
--
00000000  61626364 65666768 696a6b6c 6d6e6f70  abcdefghijklmnop
00000010  61626364 65666768 696a6b6c 6d6e6f70  abcdefghijklmnop
00000020  61626364 65666768 696a6b6c 6d6e6f70  abcdefghijklmnop
00000030  61626364 65666768 696a6b6c 6d6e6f70  abcdefghijklmnop

これを

--
00000000  61626364 65666768 696a6b6c 6d6e6f70  abcdefghijklmnop
..00000030

このように表現するようにしてみました。


・日本語出力に対応したい

wordtr(raw) を用意してみました。

puts "--", hexdump "abcdefghijklmnoあ" * 4
--
00000000  61626364 65666768 696a6b6c 6d6e6f82  abcdefghijklmno
00000010  a0616263 64656667 68696a6b 6c6d6e6f  .abcdefghijklmno
00000020  82a06162 63646566 6768696a 6b6c6d6e  あabcdefghijklmn
00000030  6f82a061 62636465 66676869 6a6b6c6d  oあabcdefghijklm
00000040  6e6f82a0                             noあ


def wordtr(str)
  ret = ''
  str.scan(/./){|word|
    len = word.size
    ret <<
    if len == 1
      word.tr("\000-\037\177-\377", ".")
    else
      word
    end
  }
  ret
end

def hexdump(str)
  offset = 0
  result = []
  preraw = nil
  preoff = nil

  while raw = str.slice(offset, 16) and raw.length > 0
    if preraw == raw
      preoff = offset
      offset += 16
      next
    end
    if preoff
      result << sprintf("..%08x", preoff)
      preoff = nil
    end
    preraw = raw

    # address field
    line = sprintf("%08x  ", offset)

    # data field
    for v in raw.unpack('N* a*')
      if v.kind_of? Integer
	line << sprintf("%08x ", v)
      else
	v.each_byte {|c| line << sprintf("%02x", c) }
      end
    end

    # text field
    line << ' ' * (47 - line.length)
    line << wordtr(raw)

    result << line
    offset += 16
  end

  if preoff
    result << sprintf("..%08x", preoff)
    preoff = nil
  end

  result
end

----
YOSHIDA Kazuhiro  moriq / moriq.com  http://www.moriq.com/