コンピュータにおける符号化の由来

5522 ワード

背景
JAvaとpythonでは符号化の問題が発生しました.たとえばeclipseで文字化けした問題、javaがデータベースの文字化けした問題、pythonでcodecで発生した問題などです.
configParser.py中国語を含むプロファイルを開くと、次のエラーが発生します.
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa1 in position 61: illegal multibyte sequence

だからシステムは符号化の知識を理解する必要がある.
コード生成の背景
各種の符号化の発生は歴史的な役割の推進の下でコンピュータが各国の文字を表現する需要を便利にすることによって生じた.最初の符号化はISO 8859-1であり、通常Latin-1と呼ばれ、彼は単バイト符号化である8ビットビットで最大256文字が英語文字しか表示できないことを示した.単バイトは漢字や日本語などでは表現できないため、マルチバイト符号化MBCS(Multi-Byte Character Set)が登場した.
シングルバイトとマルチバイトの違い--符号化表現の問題を解決
1.シングルバイトとMBCSの違い:ASCII(American Standard Code for Information Interchange)はシングルバイト符号化を使用しているが、ASCIIテーブルは8ビットbitのみを使用しており、文字の半分である126個のASCII文字を表すことができる.
したがって、第1のビットがX 80より大きいか否かによって、符号化が単バイト符号化であるか多バイト符号化であるかを判断することができる.X 80より小さい場合はASCII文字、X 80より大きい場合は1バイト目と2バイト目を合わせて1文字を表し、次のバイトをスキップして判断を続行します.
2.マルチバイトでは、コンピュータメモリの友好性と操作効率によって、定長符号化と変長符号化に分けることができる.定長符号化はコンピュータ処理に便利であるため、文字列がjavaメモリでunicode符号化されるなど、多くのソフトウェア内部でunicode符号化(2バイト定長符号化)が使用されている.
unicode符号化と国家政治を伴う符号化--歴史的要因
1.Unicodeも文字符号化方法ですが、世界中のすべての言語の文字を収容できる国際組織によって設計されています.Unicodeの学名は「UniversalMultiple-Octet Coded Character Set」で、略称はUCS.
unicodeは定長2バイト符号化を用いるため、ISO-8859-1とは互換性がない(iso 8859-1は単バイト).この2つには、符号化にunicode実ISO-8859-1の前に0が加算され、例えばaはISO 8859-1で「61」、unicodeで「0061」と表される.
2.各国の言語は必要に応じて自分のコードを出します.例えば、男性を表すために簡体字中国語を表すGB 2312と繁体字中国語のbig 5を出しました.後に玉玉GB 2312が示す男性が少なすぎてGBKコードが発売された(GBK 1.0に追加して21886個の記号が収録されている).2000年のGB 18030は、GBK 1.0に取って代わる正式な国家基準であり、チベット語、モンゴル語、ウイグル語などの主要な少数民族文字が含まれている.
一定の長さと長さ--転送とストレージ
unicodeは、すべての文字がコンピュータで処理しやすいが、転送や記憶が不便であることをほとんど表すことができる.そのため、UTF符号化が後に現れ、英語文字UTFについても1バイトで表されるので、UTF符号化はISO 8859-1と互換性がある.他の文字については、長くなった1〜6個の異なるバイト表現、例えば漢字については3個のバイト表現を用いる.
Pythonでの符号化と復号化
UTF-8,asciiコード,unicodeの由来について述べた.ここではpythonでよく遭遇する符号化と復号化の問題を解決する.
python符号化復号とは何か、符号化はunicode->strであり、復号はstr->unicode.1つのstrがどのように符号化され、どのように復号されなければ乱符号化されないかである.str 1.decode(‘gb 2312’)は、gb 2312を符号化した文字列str 1をunicodeに復号することを示す.str 2.encode(‘utf-8’)は、unicode文字列str 2をutf-8形式で符号化された文字列に変換することを示す.異なる符号化間の変換が必要な場合、str 1.decode('gb 2312').encode('utf-8')を復号してから符号化する必要がある.
#!/usr/bin/env python
# -*- coding: ascii -*-

    def testCodecs(self):
        s = '  '  #     s  ascii        
        s.encode('gb18030')
        print(sys.getdefaultencoding())

  :
  File "/Users/shawn/eclipse_workspace_pdev_group/python_works/pythonLearnCodeExample/src/str_oper/testStr.py", line 0
SyntaxError: 'ascii' codec can't decode byte 0xe2 in position 227: ordinal not in range(128)

      :
1). s = ‘  ’,        -*-coding:ascii -*-  ascii        。
2). s ascii    ,s.encode('gb18030')  S    ,   s.decode(sys.getdeaultencoding).encode('gb18030'),       ascii    ,    utf-8 decode  。

JAvaでの符号化復号
JAvaの符号化はunicodeを介して変換する必要はなく、unicodeは文字列の符号化および復号に使用することができる.ここでの関係は、1バイト1バイトのストレージを格納するときに、(意味のある文字)を原文(元の意味のある文字)に復元する必要があることを示す暗号文に似ています.
1. String.getBytes()
/**
               charset  ,        。      java      unicode     。  "  ",     (        )   "4e2d 6587",  charset "gbk",     "d6d0 cec4",      "d6 d0 ce c4"。  charset "utf8"    "e4 b8 ad e6 96 87"。   "iso8859-1",       ,     "3f 3f"(    )
*/
2. new String(byte[],charset)
/**
           ,       charset        ,     unicode  。    getBytes   ,"gbk"  "utf8"          "4e2d 6587"
*/
@Test
    public void test1()
    {
        String s = "  ";
        //   
        byte[] utf;
        try {
            utf = s.getBytes("utf-8");
            byte[] gbk = s.getBytes("gbk");
            System.out.println("utf-8  :" + Arrays.toString(utf));//[-28,-67,-96,-27,-91,-67]  6   
            System.out.println("gbk  :" + Arrays.toString(gbk));//[-60,-29,-70,-61] 4   
            //   
            String s1 = new String(utf, "utf-8"); // utf8/utf8  
            String s2 = new String(utf, "gbk"); // utf8/gbk   :  ソ gbk 2     ,        
            String s3 = new String(gbk, "utf-8"); // gbk/utf8  utf-8  :??? utf-8    6   
            String s4 = new String(gbk, "gbk"); // gbk/gbk  utf-8  :??? utf-8    6   

            System.out.println("--------------------");
            System.out.println("utf-8/utf8   :" + s1);
            System.out.println("utf8/gbk  :" + s2);
            System.out.println("gbk utf-8  :" + s3);
            System.out.println("gbk gbk  :" + s4);
            System.out.println("---------------------");
            s3 = new String(s3.getBytes("utf-8"), "gbk"); //     ?   gbk utf-8        
            System.out.println("s3 gbk utf-8  :s3.getBytes(\"utf-8\"), \"gbk\"" + s3);


            byte [] unicode = s.getBytes("unicode");
            String s5 = new String(unicode,"unicode");
            System.out.println("S5=" + s5);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
    }

実行結果:
utf-8  :[-28, -67, -96, -27, -91, -67]
gbk  :[-60, -29, -70, -61]
--------------------
utf-8/utf8   :  
utf8/gbk  :  ソ
gbk utf-8  :���
gbk gbk  :  
---------------------
s3 gbk utf-8  :s3.getBytes("utf-8"), "gbk"    �
S5=