![[Ruby] ファイルの内容を16進数とASCIIで出力する](http://www.happytrap.jp/blogs/wp-content/uploads/2012/11/default_ruby.jpg)
Linuxのコマンドhexdumpに「-C」オプションを付けて実行すると、指定したファイルの内容を16進数とASCIIで出力してくれて大変便利です。
$ hexdump -C “dog.png”
出力:
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR| 00000010 00 00 02 80 00 00 02 80 08 06 00 00 00 0c cd c9 |................| 00000020 23 00 00 00 19 74 45 58 74 53 6f 66 74 77 61 72 |#....tEXtSoftwar| 00000030 65 00 41 64 6f 62 65 20 49 6d 61 67 65 52 65 61 |e.Adobe ImageRea| (...) 0000df70 08 05 20 21 84 10 42 08 a1 00 24 84 10 42 08 21 |.. !..B...$..B.!| 0000df80 ae f3 ff 02 0c 00 d4 22 19 85 73 7e ad ea 00 00 |......."..s~....| 0000df90 00 00 49 45 4e 44 ae 42 60 82 |..IEND.B`.| 0000df9a
バイナリエディタでよく見かけるフォーマットですね。
で、ちょうどRubyに入門中なのでRubyでも同様の実装を書いてみました。
(指定するファイルはソースコードにベタで記述してしまってますが。。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | cnt = 0 ascii = '' print '%06x ' % cnt File.open('dog.png').bytes do |char| print '%02x ' % char ascii << (char.between?(32, 126) ? char : '.') if ascii.length >= 16 puts '|%s|' % ascii ascii = '' print '%06x ' % (cnt + 1) end cnt += 1 end if ascii.length > 0 print ' ' * (16 - ascii.length) puts '|%s|' % ascii end |
出力:
000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR| 000010 00 00 02 80 00 00 02 80 08 06 00 00 00 0c cd c9 |................| 000020 23 00 00 00 19 74 45 58 74 53 6f 66 74 77 61 72 |#....tEXtSoftwar| 000030 65 00 41 64 6f 62 65 20 49 6d 61 67 65 52 65 61 |e.Adobe ImageRea| (...) 00df70 08 05 20 21 84 10 42 08 a1 00 24 84 10 42 08 21 |.. !..B...$..B.!| 00df80 ae f3 ff 02 0c 00 d4 22 19 85 73 7e ad ea 00 00 |......."..s~....| 00df90 00 00 49 45 4e 44 ae 42 60 82 |..IEND.B`.|
できましたー。
でも、よくみるとLinuxコマンドの方が1行多く出力されています(0000df9a)。
なぜ?EOFの分でしょうか??
環境
Mac OS X 10.8.2
Ruby 1.9.3
Ruby 1.9.3