Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unicodeと符号化形式

 Unicodeと符号化形式

kamijin_fanta

July 26, 2021
Tweet

More Decks by kamijin_fanta

Other Decks in Technology

Transcript

  1. Unicodeと符号化形式
    2021/07/26 Tadahisa Kamijo

    View Slide

  2. Goal
    Unicode, UTF-8, UTF-16の違いを理解
    プログラミング言語ごとの文字コードの扱いを理解

    View Slide

  3. Before Unicode
    アメリカ: ASCII
    西ヨーロッパ: Laten-1
    日本: JIS X 0208 (Shift JIS, EUC-JP)
    IBM,NEC PC98が勝手に拡張した文字を統合→CP932(Windows-31J)
    中国: GB 2312-80 (EUC-CN)
    後のGB 18030が国家規格として採用・中国で対応が必須に
    台湾: CCCII (EUC-CCCII-FT)
    他にBigFive,CNS 11643等も存在
    韓国: KS X 1001 (EUC-KR)
    北朝鮮: KPS 9566 (EUC-KP)
    ベトナム: TCVN (EUC-VN)
    1980年代に言語/ベンダによって異なる文字コードが定義され普及した

    View Slide

  4. After Unicode
    1991年に制定された文字コード
    各国・各社の文字コードを統合
    Xerox,Apple,IBM,Sun,HP
    ,JustSystem, etc...
    最大約111万種の文字を定義可能

    View Slide

  5. 文字コードの大まかな種類
    符号化文字集合 / CCS (Coded Character Set)
    文字の集合に番号を振ったもの
    JIS X 0208 ("桜"は"26区89点")
    Unicode ("桜"は"U+685C")
    文字符号化方式 / CES (Coded Encoding Scheme)
    コンピュータ内での表現方法
    Shift JIS, EUC-JP
    UTF-8, UTF-16
    https://www.asahi-net.or.jp/~ax2s-kmtn/ref/jisx0208.html

    https://unicode-table.com/en/685C/

    View Slide

  6. UCS-2, UCS-4
    初期バージョンのUnicodeで定義された符号化文字集合
    Unicode 1.0.1, ISO/IEC 10646-1
    そのまま文字符号化方式としても利用されていた

    View Slide

  7. UCS-4 (Universal multi-octet Character Set 4)
    1文字を31bitで表現
    128群(group), 256面(plane), 256区(row), 256点(cell) で20億種
    UCS-2 (Universal multi-octet Character Set 2)
    1文字を16bitで表現
    0群(group), 0面(plane) の65,535種
    一般的に利用される文字はUCS-2にほぼ収録
    歴史
    当初UnicodeはUCS-2にすべての文字を収録する予定だったが、文字数の限
    界が有りUCS-4に一般的でない文字を収録
    UCS-2で収録された文字はBMP(Basic Multilingual Plane / 基本多言語面)と
    呼ばれるように

    View Slide

  8. UTF-16
    UCS-2の置き換えとして定義
    基本的には16bitで表現
    UCS-2(BMP)に無くUCS-4に収録されている文字 U+10000 ~ U+10FFFF を
    「サロゲートペア」として32bitで表現
    UTF-16の符号化
    スカラ値 | UTF-16 | 備考

    -------------------------- | ----------------------------------- | ---------

    xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx | BMPはそのまま表現

    000uuuuu xxxxxxxx xxxxxxxx | 110110ww wwxxxxxx 110111xx xxxxxxxx | wwww = uuuuu - 1

    BMPで表現できず連続した16bit符号2つで表されるペアをサロゲートペアと呼ぶ

    View Slide

  9. UTF-8
    UCS-2(UTF-16)はAsciiコードとの互換性がない
    英数字もすべて16bitで表現される
    Asciiコード互換の文字符号化方式としてUTF-8が定義された
    当初はPlan9向けにベル研究所で考案された
    https://oraccha.hatenadiary.org/entry/20081004/1223124803
    Asciiコードで利用されていない 0x80 ~ 0xFF の範囲を利用
    最初のビットでバイト数を表現
    110 2byte
    1110 3byte
    11110 4byte
    1998年のrfc2279では最大6バイト,2003年のrfc3629では4バイト

    View Slide

  10. https://ja.wikipedia.org/wiki/UTF-8

    https://oku.edu.mie-u.ac.jp/~okumura/xhtml/utf8.html

    View Slide

  11. UTF-32
    UCS-4の符号をそのまま表現
    利用可能な範囲は 0x00 ~ 0x10FFFF に制限されている

    View Slide

  12. Unicode関連の用語
    コードポイント
    任意のUnicodeコードポイント
    範囲は U+0 ~ U+10FFFF16
    Surrogate Code Point
    UTF-16のサロゲートペアに使うコードポイント
    High-Surrogate Code Point: U+D800 ~ U+DBFF
    Low-Surrogate Code Point: U+DC00 ~ U+DFF
    Unicode スカラ値
    一部の予約されたコードポイント以外の任意のUnicodeコードポイント
    U+1234 で表現
    範囲は U+0 ~ U+D7FF16 U+E00016 ~ U+10FFFF16

    View Slide

  13. 亜種1: WTF-16
    デコードできない可能性があるUTF-16をサポートするために定義
    レガシーな環境向け
    サロゲートが対応していないUTF-16文字列が不正なUTF-16だと再定義され

    互換性のために昔のUTF-16をWTF-16として呼び、扱いを分ける
    例えば
    ECMAScriptではString値を、UTF-16でデコードできない可能性のある16bit
    整数配列で表現する
    Windowsのファイルシステムはパスを、UTF-16でデコードできない可能性の
    ある16bit整数配列で表現する

    View Slide

  14. 亜種2: WTF-8
    不正でデコードできないWTF-16を強制的にUTF-8へ変換したバイト列
    サロゲートが対応していなくてもそのまま結合する
    RustのWindowsでのOsStringはWTF-8で表現

    View Slide

  15. 亜種3: CESU-8
    BMPの範囲はUTF-8と同一の表現
    BMP外の文字列のエンコードが特殊
    2つのUTF-16符号へエンコード ( → 0xD834 0xDD1E)
    2つの符号をそれぞれ16bit整数のUnicodeのコードポイントとして解釈
    (0xD834 0xDD1E→ U+D834 U+DD1E)
    UTF-8のエンコードを行う (3バイトのUTF-8が2つできる)

    View Slide

  16. Oracleしか使っていないので理解する必要はないし、今となってはOracleも使わ
    ないほうが良いと言っている
    Oracle DatabaseではCESU-8を UTF-8 , 一般的なUTF-8を AL32UTF8 として
    扱う
    MySQLも文字コードを utf8 と指定するとCESU-8が利用され、通常のUTF-
    8を utf8mb4 として扱う
    アレな実装をOracleが使い始めて規格化してしまった
    https://docs.oracle.com/cd/F19136_01/nlspg/supporting-multilingual-
    databases-with-unicode.html#GUID-F3B0B4F7-B6D9-473D-840F-
    F98998F37981

    View Slide

  17. その他、利用されていないUnicodeの符号化方式
    UTF-7
    UTF-16で表現したUnicodeをBase64で変換
    7bit単位の制約があるメール等の環境向けに作られた
    ステートフルエンコーディングでXSS等の危険性が高く現在は利用されない
    https://gihyo.jp/admin/serial/01/charcode/0001
    UTF-5
    0-9,A-Vの32文字で表現する文字符号化方式
    国際化ドメインでの利用を想定していたがPunycodeが採用されたので利用さ
    れていない
    UTF-9
    UTF-8と比較してLaten-1が1バイト・主な漢字が2バイトで表現できる
    エイプリールフールのジョークRFCで定義

    View Slide

  18. プログラミング言語とUnicode
    UTF-8のString型
    Rust, Elixir, Julia, Swift
    任意バイト列を文字列として扱う・解釈はライブラリに任される
    C, C++, Go, Rua, PHP
    , Zig
    任意バイト列・エンコーディングを別に持つ
    Ruby (CSI正規化・デフォルトはUTF8)
    UTF-16のString型
    16bit整数の配列: JavaScript, Java, C#
    Unicodeコードポイントの配列: Python

    View Slide

  19. OSとUnicode
    Windows, MacOS
    UTF-16
    NTFS, HFS+, UTF-16
    UTF-16
    ext4
    UTF-8

    View Slide

  20. 参考資料1
    .NETでの文字エンコード https://docs.microsoft.com/ja-
    jp/dotnet/standard/base-types/character-encoding-introduction
    JS Primer 文字列とUnicode https://jsprimer.net/basic/string-unicode/
    utf8 rcf
    1998 https://tools.ietf.org/html/rfc2279
    2003 https://tools.ietf.org/html/rfc3629
    What is the maximum number of bytes for a UTF-8 encoded character?
    https://stackoverflow.com/questions/9533258/what-is-the-maximum-number-
    of-bytes-for-a-utf-8-encoded-character
    結合文字 (NFC,NFD) https://tama-san.com/combining_character_sequence/

    View Slide

  21. 参考資料2
    wtf-8 https://simonsapin.github.io/wtf-8/
    Unicodeとのつきあい方
    https://www.jstage.jst.go.jp/article/konpyutariyoukyouiku/27/0/27_12/_article
    /-char/ja/
    Unicodeとは? その歴史と進化、開発者向け基礎知識
    https://www.buildinsider.net/language/csharpunicode/01
    平成17年度漢籍担当職員講習会:文字コードとテキスト処理の歴史
    http://kanji.zinbun.kyoto-u.ac.jp/~wittern/koushuukai/2005/index0.html
    第2回 ユニコードについて ENGINEER COLUMN https://www.cresco-
    es.co.jp/column/unicode02/
    UCSとUTF http://nomenclator.la.coocan.jp/unicode/ucs_utf.htm

    View Slide

  22. 参考資料3
    Wikipedia
    UTF-16 https://ja.wikipedia.org/wiki/UTF-16
    UTF-8 https://ja.wikipedia.org/wiki/UTF-8
    UTF-32 https://ja.wikipedia.org/wiki/UTF-32
    Unicode https://ja.wikipedia.org/wiki/Unicode
    WTF-8がrustで利用される
    https://twitter.com/qnighy/status/1038363399292313600

    View Slide