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)]}}