Shift_JIS(CP932)の重複している文字の列挙

なんか自分の区番号の認識が間違ってたぽい。第二バイトが40-7Eだったら奇数で80-FCだったら偶数と思ってたんだけど。正しくはどうなんだろう
区点番号は JIS X 0208 の符号みたいですね。 JIS X 0208 の第一バイト、第二バイトのそれぞれの範囲は 21-7E の 94 通りでそれに 1..94 の番号を与えたのが 区番号、点番号のようです。そして、 JIS コード順と SJIS コード順は同じなようです。さらに SJIS の第二バイトは 188 通りと 94 * 2 になっています。ということなので、SJISのコードと区点番号の相互変換は難しくなさそうです。
って、 def to_ku(n) n/94+1 end こんだけすかー。
今まで間違えていた、def to_ku(n) (n/188)*2+1+((n%188)>=63?1:0) end から直すとしたら def to_ku(n) (n/188)*2+1+((n%188)>=94?1:0) end かな。 n/94+1 のシンプルさには勝てない。
せっかくなので点番号も表示するようにかえてみた。

#!ruby-1.9
# -*- encoding: cp932 -*-
require 'pp'
require 'kconv'
require 'iconv'

# SJIS の第一バイトの (81-9F, E0-FC) から 0...60 の連番へ
def d1(c) c<160?c-129:c-193 end
# 0...60 の連番から SJIS の第一バイトの (81-9F, E0-FC) へ
def e1(m) m<31?m+129:m+193 end

# SJIS の第二バイトの (40-7E, 80-FC) から 0...188 の連番へ
def d2(c) c<127?c-64:c-65 end
# 0...188 の連番から SJIS の第二バイトの (40-7E, 80-FC) へ
def e2(m) m<63?m+64:m+65 end

# SJIS 文字から 0...11280 の連番へ
def sjis_char_to_num(c) d1(c.getbyte(0))*188+d2(c.getbyte(1)) end
# 0...11280 の連番から SJIS 文字へ
def num_to_sjis_char(n) (e1(n/188).chr+e2(n%188).chr).force_encoding('cp932') end

# SJIS 文字の連番(0...11280)から区点番号(1..120)へ
def to_kuten(n) [n/94+1,n%94+1] end

class Object
  def modify_inspect(&block)
    (class << self; self end).class_eval do
      define_method(:inspect, &block)
    end
    self
  end
end

hash = {}
to_utf8 = Iconv.new('utf-8', 'cp932')
11280.times do |i|
  c = num_to_sjis_char(i)
  #c = c.encode('utf-8') rescue next
  #c = c.kconv('utf-8')
  c = to_utf8.iconv(c) rescue next
  if hash.key?(c)
    hash[c] << i
  else
    hash[c] = [i]
  end
end
pp hash.select{|k,v| v.size > 1}\
       .map{|k,v|
         v.map{|i|[num_to_sjis_char(i),
                   num_to_sjis_char(i).modify_inspect{
                     '"'+each_byte.map{|i|'\x%02x'%i}.join+'"'},
                   i,
                   to_kuten(i)]}}