● perl の場合
◆ UNICODE( 0-0x10FFFF )→UTF-8(2020-10-30 更新)
U+10000 以降コード対応。
▼ perl で UNICODE( 0-0x10FFFF )→UTF-8
sub UC16toUTF8 { my $c = $_[0]; # ( 0-0x10FFFF ) return ( $c < 128 )? chr( $c ): ( ($c < 0x800 ? (chr( 0xC0 +( ($c >> 6)& 0x1F ) ) ): ( ($c < 0x10000 ? chr( 0xE0 +( ($c >> 12)& 0x0F ) ):( chr( 0xF0 +( ($c >> 18)& 0x07 ) ). chr( 0x80 +( ($c >> 12)& 0x3F ) ) ) ). chr( 0x80 +( ($c >> 6)& 0x3F ) ) ) ). chr( 0x80 +( $c & 0x3F ) ) ); }
2行めにある条件式を ( $c < 128 && $c != 0 ) にすると,C言語の ASCIZ 文字列内で「ヌル文字('¥0')」を扱う時にも使えるはず。
● JavaScript の場合
◆ 文字列→UNICODE(2020-10-31 更新)
ある程度新しいブラウザなら,以下の関数が使えるもよう。
- str.charCodeAt( pos )
文字列 str の pos 文字目の UNICODE 文字コードを求める。ただし,戻り値は 16 ビット限定で,U+10000 以降はサロゲートペアの前(0xD800~0xDBFF)と後(0xDC00~0xDFFF)の 16 ビットが別々に求まる。つまり「2文字」扱いになるため,16 ビットを越える正確な文字コードを得たい場合は,次の文字のコード(つまり pos + 1)と組み合わせて計算する必要がある。
- str.codePointAt( pos )
文字列 str の pos 文字目の UNICODE 文字コードを求める。U+10000 以降もサロゲートペアは使われず,16 ビットを越える正確な文字コードが得られるよう。
以下,これらが使えない場合の回避関数。
1文字だけの場合はこの辺りがシンプルかな。U+10000 以降のコードは,escape 関数により "%uXXXX%uYYYY" のサロゲートペアに直されることが前提。ただ,後半(YYYY)が 0xDC00~0xDFFF かどうかの確認は省略しているが。
▼ JavaScript で文字コードを得る
function chcode( chr ){ // 1文字,U+10000 以降コード対応版 var ascii =' !"#$%&\'()*+,-./0123456789:;<=>?'+ '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'+ '`abcdefghijklmnopqrstuvexyz{|}~'; var c, d; if( 0 <=(c = ascii.indexOf( chr ))) return( c + 32 ); else { c = escape( chr ); d = parseInt( c.substr( c.charAt(1)=='u'? 2: 1, 4 ), 16 ); if( (d & 0xFC00)== 0xD800 ) d =(((d & 0x3FF)+ 0x40)<< 10)+ (parseInt( c.substr( 8 ), 16 )& 0x3FF); return( d ); } }