チェックサム

昔懐かし(?)チェックサムを表示するプログラムです。

class ChecksumPrinter
  def initialize(io, columns = 16, rows = 16)
    @columns, @rows = columns, rows
    @buffer_size = @columns * @rows
    @sums = Array.new(@buffer_size)
    @io = io
    @io.binmode
  end

  def start(&block)
    block ||= proc {|page| print page }
    loop do
      buffer = @io.read(@buffer_size)
      break unless buffer
      buffer << "\0" * (@buffer_size - buffer.length)
      block.call(checksum(buffer))
    end
  end

  def checksum(buffer)
    sum = 0
    @sums.fill(0)
    result = ""
    (0...@buffer_size).each do |i|
      sum += buffer[i]
      @sums[i % @columns] += buffer[i]
      result << sprintf("%02X ", buffer[i])
      if i % @columns == @columns - 1
        result << sprintf("| %02X \n", sum % 256)
        sum = 0
      end
    end
    result << "---" * @columns + "+---\n"

    (0...@columns).each do |i|
      result << sprintf("%02X ", @sums[i] % 256)
      sum += @sums[i]
    end
    result << sprintf("| %02X \n\n", sum % 256)
  end
end

ChecksumPrinter.new(ARGF).start

実行結果です。

> ruby a.rb a.rb
63 6C 61 73 73 20 43 68 65 63 6B 73 75 6D 50 72 | 2B
69 6E 74 65 72 0D 0A 20 20 64 65 66 20 69 6E 69 | 08
74 69 61 6C 69 7A 65 28 69 6F 2C 20 63 6F 6C 75 | F1
6D 6E 73 20 3D 20 31 36 2C 20 72 6F 77 73 20 3D | A6
20 31 36 29 0D 0A 20 20 20 20 40 63 6F 6C 75 6D | A7
6E 73 2C 20 40 72 6F 77 73 20 3D 20 63 6F 6C 75 | 68
6D 6E 73 2C 20 72 6F 77 73 0D 0A 20 20 20 20 40 | 3C
62 75 66 66 65 72 5F 73 69 7A 65 20 3D 20 40 63 | B4
6F 6C 75 6D 6E 73 20 2A 20 40 72 6F 77 73 0D 0A | 2A
20 20 20 20 40 73 75 6D 73 20 3D 20 41 72 72 61 | 8B
79 2E 6E 65 77 28 40 62 75 66 66 65 72 5F 73 69 | 0E
7A 65 29 0D 0A 20 20 20 20 40 69 6F 20 3D 20 69 | 9D
6F 0D 0A 20 20 20 20 40 69 6F 2E 62 69 6E 6D 6F | 61
64 65 0D 0A 20 20 65 6E 64 0D 0A 0D 0A 20 20 64 | 29
65 66 20 73 74 61 72 74 28 26 62 6C 6F 63 6B 29 | 9B
0D 0A 20 20 20 20 62 6C 6F 63 6B 20 7C 7C 3D 20 | 17
------------------------------------------------+---
D1 39 67 FB 60 16 8E 0E 15 28 DD 89 46 C1 D2 6B | 65

...

75 6D 20 25 20 32 35 36 29 0D 0A 20 20 20 20 20 | C4
20 20 20 73 75 6D 20 3D 20 30 0D 0A 20 20 20 20 | F9
20 20 65 6E 64 0D 0A 20 20 20 20 65 6E 64 0D 0A | 5C
20 20 20 20 72 65 73 75 6C 74 20 3C 3C 20 22 2D | 26
2D 2D 22 20 2A 20 40 63 6F 6C 75 6D 6E 73 20 2B | 72
20 22 2B 2D 2D 2D 5C 6E 22 0D 0A 0D 0A 20 20 20 | 6E
20 28 30 2E 2E 2E 40 63 6F 6C 75 6D 6E 73 29 2E | 9A
65 61 63 68 20 64 6F 20 7C 69 7C 0D 0A 20 20 20 | 7C
20 20 20 72 65 73 75 6C 74 20 3C 3C 20 73 70 72 | 0C
69 6E 74 66 28 22 25 30 32 58 20 22 2C 20 40 73 | 1B
75 6D 73 5B 69 5D 20 25 20 32 35 36 29 0D 0A 20 | D8
20 20 20 20 20 73 75 6D 20 2B 3D 20 40 73 75 6D | 32
73 5B 69 5D 0D 0A 20 20 20 20 65 6E 64 0D 0A 20 | 99
20 20 20 72 65 73 75 6C 74 20 3C 3C 20 73 70 72 | 0C
69 6E 74 66 28 22 7C 20 25 30 32 58 20 5C 6E 5C | BC
6E 22 2C 20 73 75 6D 20 25 20 32 35 36 29 0D 0A | 73
------------------------------------------------+---
2F CB F5 B1 33 69 CA 56 15 84 9A AA 69 02 1C 7A | 3A

20 20 65 6E 64 0D 0A 65 6E 64 0D 0A 0D 0A 43 68 | 9E
65 63 6B 73 75 6D 50 72 69 6E 74 65 72 2E 6E 65 | 6D
77 28 41 52 47 46 29 2E 73 74 61 72 74 0D 0A 00 | 5B
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00
------------------------------------------------+---
FC AB 11 33 20 C0 83 05 4A 46 E2 E1 F3 45 BB CD | 66