【13】符号化、復号化および乱符号化


符号化、復号化、文字化け


一、常用文字セットと符号化


1.ASCIIアメリカ情報交換標準コード

  • 符号化規則:7ビットが1文字を表す128文字
  • 欠点:26個のラテン文字、アラビア数字、英語の句読点
  • しか表示できません.

    2.EASCIIヨーロッパ拡張文字セット

  • 符号化規則:8ビットは1文字を表し、256文字
  • 欠点:一部の西欧言語の文字表示の問題は解決されたが、他の多くの言語には依然として
  • 力がない.

    3.GB 2312/GB 2312-80などの中国語文字セット

  • 符号化規則:127番の文字をキャンセル(すなわちEASCII)、128より大きい2つの文字が1つの漢字を表し、高バイトは0 xA 1から0 xF 7、低バイトは0 xA 1から0 xFE
  • である.
  • GBK中国語文字セット、マイクロソフトはGB 2312-80を拡張した後、GBK符号化を制定した.

  • 4.Unicode統一文字セット

  • には10万文字以上が含まれており、コンピュータが世界の数十言語を解析できるようにしています.
  • 符号化規則:アルファベット、記号、文字を4バイトの数字で表す.
  • Unicodeは文字セットを指し、UTF-32、UTF-16、UTF-8は符号化スキームを指す.

  • 4.1 UTF-32

  • 符号化ルール:上記Unicodeの4バイトの数字でアルファベット、記号、文字
  • を表す.

    4.2 UTF-16

  • 符号化規則:文字符号化Uが0 x 10000未満、すなわち10進数未満の65535であれば、2バイトで表す.
  • 文字符号化Uが0 x 10000より大きく、すなわち10進数の65535より大きい場合、4バイトで表される.

  • 4.3 UTF-8

  • は、Unicodeに対する可変長文字符号化であり、Unicodeの任意の文字を表すことができ、符号化の最初のバイトはASCIIと互換性がある.
  • 符号化規則は、1〜4バイトを用いて各文字を符号化する:
  • .
  • ,128個のUS-ACSCII文字は、U+0000からU+007 F
  • まで1バイトで符号化する必要がある.
  • 付加符号付きラテン語、ギリシャ語、シリル文字、アルメニア語、ヘブライ語、アラビア語、シリア語などは、2バイト目の符号化を用いてU+0080からU+07 FF
  • まで
  • その他の基本マルチテキスト平面の文字は、3バイト符号化
  • を用いる.
  • その他のごくわずかな補助平面における文字は、4バイト符号化
  • を用いる.

    二、文字化けし問題の詳しい解


    1.文字化けしの根本原因

  • 乱符号化の根本的な原因は、データの符号化と復号に使用される符号テーブルが一致しないことである.
  • データ符号化後は、バイト配列でディスクに保存されるか、ネットワークで伝送され、データ受信側がデータ送信側が使用するコードテーブルを知らない場合、ローカル定義のコードテーブルを使用して復号される.両者が一致しないと、文字化けしてしまう可能性があります!
  • 上記のコードテーブルでは、ISO 8859-1、UTF-8、GBKなどがASCIIコードテーブルへの拡張であることが知られているので、ディスクやネットワークに保存されて伝送されるASCIIコードテーブルに定義された文字(26文字のアルファベット、アラビア数字、英語の句読点)は文字化けになりません.一方、中国語文字は、ASCIIコードテーブルやISO 8859-1では1バイトでは表せないが、GBKでは2バイト、UTF-8では3バイトで表されるのが、この違いが文字化けしの深層原因となっている.

  • 2.トランスコード


    一連の符号表1で符号化されたデータは、符号表2に復号された後に一連の文字化けしが発生し、識別可能な内容をどのように取得するかを尋ねる.
    1.文字化けを符号表2でバイト配列に再符号化する.
    2.データをコードテーブル1で復号する.すなわちstr=newString(str.getBytes(「コードテーブル2」)、「コードテーブル1」)である.

    3.URLコード


    3.1基準による


    2005年1月に発表されたRFC 3986[1]は、すべての新しいURIが未予約文字をパーセンテージ符号化しないことを強制した.他の文字は、まずUTF-8バイトシーケンスに変換し、そのバイト値にパーセント符号化を使用します.これまでのURIはこの基準の影響を受けなかった.

    3.2 URIの文字タイプ


    URIで許可される文字は、予約と未予約に分けられます.保持文字は、特殊な意味を有する文字である.例えば、斜線文字は、URL(より一般的なURI)の異なる部分の境界文字に用いる.未予約文字にはこれらの特別な意味はない.パーセンテージ符号化は、保持文字を特殊文字シーケンスとして表す.上記の状況はURIとURIの異なるバージョンによって規格がわずかに変化する.
  • RFC3986section2.2予約文字(2005年1月)
  •  ! * ' ( ) ; : @ & = + $ , / ? # [ ] 
  • RFC3986section2.3未予約文字(2005年1月)
  •  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z  
     a b c d e f g h i j k l m n o p q r s t u v w x y z 
     0 1 2 3 4 5 6 7 8 9 - _ . ~ 
  • URIの他の文字はパーセンテージで符号化する必要があります.

  • 3.3 URL符号化と復号化のプロセス

  • ブラウザはutf-8符号化URLの非保持文字(保持文字および他の文字を含む)を使用して、バイト毎に対応する16進数表現に基づいて%で区切られたバイト配列を得る.
  • サーバはデータを受け取り、URL復号を行い、復号根拠はutf-8符号表である.
  • サーバは、自身のコードテーブルで再符号化する.

  • 4.サーブレットでの文字化けしの問題


    4.1 Requestメッセージの文字化けし

  • パッケージRequestオブジェクトの符号化フォーマットが指定されていない場合、サーブレットはISO 8859-1符号化をデフォルトで使用し、中国語が文字化されない.
  • Requestエンティティ(POST要求から)のコンテンツについては、setCharacterEncoding(“utf-8”)を使用して符号化コードテーブルを指定することができる.
    // 
    Overrides the name of the character encoding used in the body of this request.
  • は、Requestヘッダ(GETからの要求)の内容について、setCharacterEncoding(“utf-8”)によって乱符号化問題を解決することはできない.
  • は、トランスコードnewString(str.getBytes("iso8859-1"),"utf-8");またはURLを用いる復号URLDecoder.decode(“ ”)によってのみ解決できる.

    4.2 Responseメッセージの文字化けし

  • パッケージResponseオブジェクトの符号化フォーマットが指定されていない場合、サーブレットはISO 8859-1符号化をデフォルトで使用し、中国語が文字化されない.
  • は、setCharacterEncoding(“utf-8”)を使用してサーブレット符号化時にUTF-8を使用することを指定することができるが、ブラウザはサーバの応答を復号するためにどのコードテーブルを使用すべきか分からない.
  • 使用setContentType(“text/html;charset=utf-8”)は、サーブレット符号化がUTF-8を使用することを指定してもよいし、ブラウザに復号時にUTF-8を使用することを伝えることもできる.