Unicodeの基本多言語面(BMP)外、つまりUnicodeスカラ値がU+10000以降の文字について、(UTF-16の)サロゲートペアのコードを求めたい、という需要があった。これは、Win32 APIのSendInput関数がUnicodeの値をUnsigned Shortでしか指定できないので、BMP外の文字はサロゲートペアで入力しないといけないということに対応するため。
Python3においては文字列(str型)はUnicode文字列を指すので、以下文字列とだけ書く。Python2の場合は適当に読み替えてください。
文字列をUTF-16のコードポイント(整数)のリストに変換
def str_to_utf16codepoints(s): bs = s.encode(encoding='utf_16_be') return [int.from_bytes(bs[n:n+2], 'big') for n in range(0, len(bs), 2)]
文字列をUTF-16-BE(ビッグエンディアン)の文字列に変換し、2バイトごとに区切って整数に変換する。
str_to_utf16codepoints("sushi寿司🍣")
は
[115, 117, 115, 104, 105, 23551, 21496, 55356, 57187]
を返す。
UTF-16のコードポイントのリスト→文字列
上の逆変換。
def utf16codepoints_to_str(ns): bs = b''.join([n.to_bytes(2, byteorder="big") for n in ns]) s = bs.decode('utf_16_be') return s
要素技術
バイト列を整数(int型)に変換
Python 3.2以降だとint.from_bytes()が使えるらしい。1つ目の引数はバイト列、2つめはエンディアンの指定。
int.from_bytes(b'\xff\xf0', 'big')
みたいな感じでいける。
さもなくば
def int_from_bytes(bytes): val = 0 for b in bytes: val = (val << 8) + b return val
とかでできると思う。