UCS-2 UTF-8 変換

UCS-2 というのは2バイトの Unicode文字集合(およびそのコード表)のことである。
UTF-8 というのは、「ASCII と互換性のある多バイト Unicode の符号化」のことである。

Linux の man page
http://www.linux.or.jp/JM/html/LDP_man-pages/man7/utf-8.7.html
あたりを参考にして、UCS-2UTF-8 の変換コードを Ruby 1.8 で書いてみた。

やっつけで書いたので内容は保障しないが、私が必要とする範囲では動いている。
参考までに。

def utf8_to_ucs2(ch)
  if ch[0] & 0b1000_0000 == 0
    return ch[0]
  end
  
  if ch[0] & 0b1110_0000 == 0b1100_0000 
     c1 = (ch[0] & 0b0001_1111) << 6
     c2 = ch[1] & 0b0011_1111
     c = c1 + c2
     raise unless 0x0080 <= c && c <= 0x07FF
     return c
  end
   
  if ch[0] & 0b1111_0000 == 0b1110_0000 
     c1 = (ch[0] & 0b0000_1111) << 12
     c2 = (ch[1] & 0b0011_1111) << 6
     c3 = ch[2] & 0b0011_1111
     c = c1 + c2 + c3
     raise unless 0x0800  <= c && c <= 0xFFFF
     return c
  end

  raise
end

def ucs2_to_utf8(c)
  raise if c < 0
  return sprintf("%c", c) if c <= 0x7F
  if c <= 0x07FF
      c1 = 0b1100_0000 | (c >> 6)
      c2 = 0b1000_0000 | (c & 0b111111)
      return sprintf("%c%c", c1, c2)
  end
  if c <= 0xFFFF
      c1 = 0b1110_0000 | (c >> 12)
      c2 = 0b1000_0000 | ((c >> 6) & 0b111111)
      c3 = 0b1000_0000 | (c & 0b111111)
      return sprintf("%c%c%c", c1, c2, c3)
  end
  raise
end

テストコード

s = ""
puts s.size          # => 3
puts s[0].to_s(16)   # => e3
puts s[1].to_s(16)   # => 81
puts s[2].to_s(16)   # => 82
puts utf8_to_ucs2(s)    # => 12354

s = ucs2_to_utf8(12354)
puts s.size          # => 3
puts s[0].to_s(16)   # => e3
puts s[1].to_s(16)   # => 81
puts s[2].to_s(16)   # => 82