編碼規範

  • UTF-8是一種變長字節編碼方式。對於某一個字符的UTF-8編碼,如果只有一個字節則其最高二進制位爲0;如果是多字節,其第一個字節從最高位開始,連續的二進制位值爲1的個數決定了其編碼的位數,其餘各字節均以10開頭。UTF-8最多可用到6個字節。 因此UTF-8中可以用來表示字符編碼的實際位數最多有31位,即上表中x所表示的位。除去那些控制位(每字節開頭的10等),這些x表示的位與UNICODE編碼是一一對應的,位高低順序也相同。  實際將UNICODE轉換爲UTF-8編碼時應先去除高位0,然後根據所剩編碼的位數決定所需最小的UTF-8編碼位數。  因此那些基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一個字節的UTF-8編碼(7個二進制位)便可以表示。

    如下: 
    1字節 0xxxxxxx 
    2字節 110xxxxx 10xxxxxx 
    3字節 1110xxxx 10xxxxxx 10xxxxxx 
    4字節 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
    5字節 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
    6字節 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  • 編碼單位

    最小的單元是位(bit),接着是字節(Byte),一個字節=8位,英語表示是1 byte=8 bits 。機器語言的單位Byte。1 KB=1024 Byte; 1 MB=1024 KB;  1 GB=1024 MB ;  1TB=1024 GB。

    進制

    二進制數由0和1,八進制數由0-7, 十進制數由0-9,十六進制數由0-9,A,B,C,D,E,F組成,他們關係如下:
    Binary(2)
    Octal(8)
    Decimal(10)
    Hex(16)
    0
    0
    0
    00
    1
    1
    1
    1
    10
    2
    2
    2
    11
    3
    3
    3
    100
    4
    4
    4
    101
    5
    5
    5
    110
    6
    6
    6
    111
    7
    7
    7
    1000
    10
    8
    8
    1001
    11
    9
    9
    1010
    12
    10
    A
    1011
    13
    11
    B
    1100
    14
    12
    C
    1101
    15
    13
    D
    1110
    16
    14
    E
    1111
    17
    15
    F

    上層字符

    字符是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。字符集是多個字符的集合,字符集種類較多,每個字符集包含的字符個數不同,常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、 GB 18030字符集、Unicode字符集等。計算機要準確的處理各種字符集文字,需要進行字符編碼,以便計算機能夠識別和存儲各種文字。

    編輯本段編碼分類

    ASCII(American Standard Code for Information Interchange,美國信息互換標準代碼)是基於羅馬字母表的一套電腦編碼系統,它主要用於顯示現代英語和其他西歐語言。它是現今最通用的單字節編碼系統,並等同於國際標準ISO 646。
    包含內容:
    控制字符回車鍵、退格、換行鍵等。
    可顯示字符:英文大小寫字符、阿拉伯數字和西文符號
    ASCII擴展字符集擴展:表格符號、計算符號、希臘字母和特殊的拉丁符號。
    第0~31號及第127號(共33個)是控制字符或通訊專用字符,如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BEL(振鈴)等;通訊專用字符:SOH(文頭)、EOT(文尾)、ACK(確認)等;
    第32~126號(共94個)是字符,其中第48~57號爲0~9十個阿拉伯數字;65~90號爲26個大寫英文字母,97~122號爲26個小寫英文字母,其餘爲一些標點符號、運算符號等。 注意:在計算機的存儲單元中,一個ASCII碼值佔一個字節(8個二進制位),其最高位(b7)用作奇偶校驗位。所謂奇偶校驗,是指在代碼傳送過程中用來檢驗是否出現錯誤的一種方法,一般分奇校驗和偶校驗兩種。奇校驗規定:正確的代碼一個字節中1的個數必須是奇數,若非奇數,則在最高位b7添1;偶校驗規定:正確的代碼一個字節中1的個數必須是偶數,若非偶數,則在最高位b7添1。
    八進制
    十六進制
    十進制
    字符
    八進制
    十六進制
    十進制
    字符
    0
    0
    0
    nul
    100
    40
    64
    @
    1
    1
    1
    soh
    101
    41
    65
    A
    2
    2
    2
    stx
    102
    42
    66
    B
    3
    3
    3
    etx
    103
    43
    67
    C
    4
    4
    4
    eot
    104
    44
    68
    D
    5
    5
    5
    enq
    105
    45
    69
    E
    6
    6
    6
    ack
    106
    46
    70
    F
    7
    7
    7
    bel
    107
    47
    71
    G
    10
    8
    8
    bs
    110
    48
    72
    H
    11
    9
    9
    ht
    111
    49
    73
    I
    12
    0a
    10
    nl
    112
    4a
    74
    J
    13
    0b
    11
    vt
    113
    4b
    75
    K
    14
    0c
    12
    ff
    114
    4c
    76
    L
    15
    0d
    13
    er
    115
    4d
    77
    M
    16
    0e
    14
    so
    116
    4e
    78
    N
    17
    0f
    15
    si
    117
    4f
    79
    O
    20
    10
    16
    dle
    120
    50
    80
    P
    21
    11
    17
    dc1
    121
    51
    81
    Q
    22
    12
    18
    dc2
    122
    52
    82
    R
    23
    13
    19
    dc3
    123
    53
    83
    S
    24
    14
    20
    dc4
    124
    54
    84
    T
    25
    15
    21
    nak
    125
    55
    85
    U
    26
    16
    22
    syn
    126
    56
    86
    V
    27
    17
    23
    etb
    127
    57
    87
    W
    30
    18
    24
    can
    130
    58
    88
    X
    31
    19
    25
    em
    131
    59
    89
    Y
    32
    1a
    26
    sub
    132
    5a
    90
    Z
    33
    1b
    27
    esc
    133
    5b
    91
    [
    34
    1c
    28
    fs
    134
    5c
    92
    \
    35
    1d
    29
    gs
    135
    5d
    93
    ]
    36
    1e
    30
    re
    136
    5e
    94
    ^
    37
    1f
    31
    us
    137
    5f
    95
    _
    40
    20
    32
    sp
    140
    60
    96
    '
    41
    21
    33
    !
    141
    61
    97
    a
    42
    22
    34
    "
    142
    62
    98
    b
    43
    23
    35
    #
    143
    63
    99
    c
    44
    24
    36
    $
    144
    64
    100
    d
    45
    25
    37
    %
    145
    65
    101
    e
    46
    26
    38
    &
    146
    66
    102
    f
    47
    27
    39
    `
    147
    67
    103
    g
    50
    28
    40
    (
    150
    68
    104
    h
    51
    29
    41
    )
    151
    69
    105
    i
    52
    2a
    42
    *
    152
    6a
    106
    j
    53
    2b
    43
    +
    153
    6b
    107
    k
    54
    2c
    44
    ,
    154
    6c
    108
    l
    55
    2d
    45
    -
    155
    6d
    109
    m
    56
    2e
    46
    .
    156
    6e
    110
    n
    57
    2f
    47
    /
    157
    6f
    111
    o
    60
    30
    48
    0
    160
    70
    112
    p
    61
    31
    49
    1
    161
    71
    113
    q
    62
    32
    50
    2
    162
    72
    114
    r
    63
    33
    51
    3
    163
    73
    115
    s
    64
    34
    52
    4
    164
    74
    116
    t
    65
    35
    53
    5
    165
    75
    117
    u
    66
    36
    54
    6
    166
    76
    118
    v
    67
    37
    55
    7
    167
    77
    119
    w
    70
    38
    56
    8
    170
    78
    120
    x
    71
    39
    57
    9
    171
    79
    121
    y
    72
    3a
    58
    :
    172
    7a
    122
    z
    73
    3b
    59
    ;
    173
    7b
    123
    {
    74
    3c
    60
    <
    174
    7c
    124
    |
    75
    3d
    61
    =
    175
    7d
    125
    }
    76
    3e
    62
    >
    176
    7e
    126
    ~
    77
    3f
    63
    ?
    177
    7f
    127
    del
    GB2312又稱爲GB2312-80字符集,全稱爲《信息交換用漢字編碼字符集·基本集》,由原中國國家標準總局發佈,1981年5月1日實施,是中國國家標準的簡體中文字符集。它所收錄的漢字已經覆蓋99.75%的使用頻率,基本滿足了漢字的計算機處理需要。在中國大陸新加坡獲廣泛使用。
    GB2312收錄簡化漢字及一般符號、序號、數字、拉丁字母、日文假名、希臘字母、俄文字母、漢語拼音符號、漢語注音字母,共 7445 個圖形字符。其中包括6763個漢字,其中一級漢字3755個,二級漢字3008個;包括拉丁字母、希臘字母、日文平假名及片假名字母、俄語西裏爾字母在內的682個全角字符
    GB2312中對所收漢字進行了“分區”處理,每區含有94個漢字/符號。這種表示方式也稱爲區位碼。
    它是用雙字節表示的,兩個字節中前面的字節爲第一字節,後面的字節爲第二字節。習慣上稱第一字節爲“高字節” ,而稱第二字節爲“低字節”。“高位字節”使用了0xA1-0xF7(把01-87區的區號加上0xA0),“低位字節”使用了0xA1-0xFE(把01-94加上0xA0)。
    以GB2312字符集的第一個漢字“啊”字爲例,它的區號16,位號01,則區位碼是1601,在大多數計算機程序中,高字節和低字節分別加0xA0得到程序的漢字處理編碼0xB0A1。計算公式是:0xB0=0xA0+16, 0xA1=0xA0+1。
    3.GBK
    GBK字符集是GB2312的擴展(K),GBK1.0收錄了21886個符號,它分爲漢字區和圖形符號區,漢字區包括21003個字符。GBK字符集主要擴展了繁體中文字的支持。
    BIG5又稱大五碼或五大碼,1984年由臺灣財團法人信息工業策進會和五間軟件公司宏碁 (Acer)、神通 (MiTAC)、佳佳、零壹 (Zero One)、大衆 (FIC)創立,故稱大五碼。Big5碼的產生,是因爲當時臺灣不同廠商各自推出不同的編碼,如倚天碼、IBM PS55、王安碼等,彼此不能兼容;另一方面臺灣政府當時尚未推出官方的漢字編碼,而中國大陸的GB2312編碼亦未有收錄繁體中文字。
    Big5字符集共收錄13,053箇中文字,該字符集在中國臺灣使用。耐人尋味的是該字符集重複地收錄了兩個相同的字:“兀”(0xA461及0xC94A)、“嗀”(0xDCD1及0xDDFC)。
    Big5碼使用了雙字節儲存方法,以兩個字節來編碼一個字。第一個字節稱爲“高位字節”,第二個字節稱爲“低位字節”。高位字節的編碼範圍0xA1-0xF9,低位字節的編碼範圍0x40-0x7E及0xA1-0xFE。
    儘管Big5碼內包含一萬多個字符,但是沒有考慮社會上流通的人名、地名用字、方言用字、化學及生物科等用字,沒有包含日文平假名及片假字母。
    例如臺灣視“着”爲“著”的異體字,故沒有收錄“着”字。康熙字典中的一些部首用字(如“亠”、“疒”、“辵”、“癶”等)、常見的人名用字(如“堃”、“煊”、“栢”、“喆”等) 也沒有收錄到Big5之中。
    GB18030的全稱是GB18030-2000《信息交換用漢字編碼字符集基本集的擴充》,是我國政府於2000年3月17日發佈的新的漢字編碼國家標準,2001年8月31日後在中國市場上發佈的軟件必須符合本標準。GB 18030字符集標準的出臺經過廣泛參與和論證,來自國內外知名信息技術行業的公司,信息產業部和原國家質量技術監督局聯合實施。
    GB 18030字符集標準解決漢字、日文假名、朝鮮語和中國少數民族文字組成的大字符集計算機編碼問題。該標準的字符總編碼空間超過150萬個編碼位,收錄了27484個漢字,覆蓋中文、日文、朝鮮語和中國少數民族文字。滿足中國大陸香港臺灣日本韓國東亞地區信息交換多文種、大字量、多用途、統一編碼格式的要求。並且與Unicode 3.0版本兼容,填補Unicode擴展字符字彙“統一漢字擴展A”的內容。並且與以前的國家字符編碼標準(GB2312,GB13000.1)兼容。
    編碼方法:
    GB 18030標準採用單字節、雙字節和四字節三種方式對字符編碼。單字節部分使用0×00至0×7F碼(對應於ASCII碼的相應碼)。雙字節部分,首字節碼從0×81至0×FE,尾字節碼位分別是0×40至0×7E和0×80至0×FE。四字節部分採用GB/T 11383未採用的0×30到0×39作爲對雙字節編碼擴充的後綴,這樣擴充的四字節編碼,其範圍爲0×81308130到0×FE39FE39。其中第一、三個字節編碼碼位均爲0×81至0×FE,第二、四個字節編碼碼位均爲0×30至0×39。
    按照程序員的稱呼,GB2312、GBK到GB18030都屬於雙字節字符集(DBCS)。
    接着是國際通用的unicode字符集
    不同的國家和地區制定了不同的標準,由此產生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節來代表一個字符的各種漢字延伸編碼方式,稱爲 ANSI 編碼。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文操作系統下,ANSI 編碼代表 JIS 編碼。
    1.名稱的由來
    Unicode字符集編碼是(Universal Multiple-Octet Coded Character Set) 通用多八位編碼字符集的簡稱,支持世界上超過650種語言的國際字符集。Unicode允許在同一服務器上混合使用不同語言組的不同語言。它是由一個名爲 Unicode 學術學會(Unicode Consortium)的機構制訂的字符編碼系統,支持現今世界各種不同語言的書面文本的交換、處理及顯示。該編碼於1990年開始研發,1994年正式公佈,最新版本是2005年3月31日的Unicode 4.1.0。Unicode是一種在計算機上使用的字符編碼。它爲每種語言中的每個字符設定了統一併且唯一的二進制編碼,以滿足跨語言、跨平臺進行文本轉換、處理的要求。
    2.編碼方法
    Unicode 標準始終使用十六進制數字,而且在書寫時在前面加上前綴“U+”,例如字母“A”的編碼爲 004116 。所以“A”的編碼書寫爲“U+0041”。
    3.UTF-8 編碼
    UTF-8是Unicode的其中一個使用方式。 UTF是 Unicode Translation Format,即把Unicode轉做某種格式的意思。
    UTF-8便於不同的計算機之間使用網絡傳輸不同語言和編碼的文字,使得雙字節的Unicode能夠在現存的處理單字節的系統上正確傳輸。
    UTF-8使用可變長度字節來儲存 Unicode字符,例如ASCII字母繼續使用1字節儲存,重音文字、希臘字母或西裏爾字母等使用2字節來儲存,而常用的漢字就要使用3字節。輔助平面字符則使用4字節
    4.UTF-16 和 UTF-32 編碼
    UTF-32、UTF-16和 UTF-8 是 Unicode 標準的編碼字符集字符編碼方案,UTF-16 使用一個或兩個未分配的 16 位代碼單元的序列對 Unicode 代碼點進行編碼;UTF-32 即將每一個 Unicode 代碼點表示爲相同值的 32 位整數
    通過一個問題了解unicode編碼
    問題:使用Windows記事本的“另存爲”,可以在ANSI、GBK、Unicode、Unicode big endian和UTF-8這幾種編碼方式間相互轉換。同樣是txt文件,Windows怎樣識別編碼方式的呢?
    我很早前就發現Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會多出幾個字節,分別是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但這些標記是基於什麼標準呢?
    答案:
    ANSI字符集定義:ASCII字符集,以及由此派生併兼容的字符集,如:GB2312,正式的名稱爲MBCS(Multi-Byte Chactacter System,多字節字符系統),通常也稱爲ANSI字符集。
    UNICODE 與 UTF8、UTF16
    由於每種語言都制定了自己的字符集,導致最後存在的各種字符集實在太多,在國際交流中要經常轉換字符集非常不便。因此,產生了Unicode字符集,它固定使用16 bits(兩個字節)來表示一個字符,共可以表示65536個字符
    標準的 Unicode 稱爲UTF-16(UTF:UCS Transformation Format )。後來爲了雙字節的Unicode能夠在現存的處理單字節的系統上正確傳輸,出現了UTF-8,使用類似MBCS的方式對Unicode進行編碼。(Unicode字符集有多種編碼形式)
    例如"連通"兩個字的Unicode標準編碼UTF-16 (big endian)爲:DE 8F 1A 90
    而其UTF-8編碼爲:E8 BF 9E E9 80 9A
    當一個軟件打開一個文本時,它要做的第一件事是決定這個文本究竟是使用哪種字符集的哪種編碼保存的。軟件一般採用三種方式來決定文本的字符集和編碼:
    檢測文件頭標識,提示用戶選擇,根據一定的規則猜測
    最標準的途徑是檢測文本最開頭的幾個字節,開頭字節 Charset/encoding,如下表:
    EF BB BF : UTF-8
    FF FE : UTF-16/UCS-2, little endian
    FE FF : UTF-16/UCS-2, big endian
    FF FE 00 00 : UTF-32/UCS-4, little endian.
    00 00 FE FF : UTF-32/UCS-4, big-endian.
    1、big endian和little endian
    big endian和little endian是CPU處理多字節數的不同方式。例如“漢”字的Unicode編碼是6C49。那麼寫到文件裏時,究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big endian。還是將49寫在前面,就是little endian。
    “endian”這個詞出自《格列佛遊記》。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。
    我們一般將endian翻譯成“字節序”,將big endian和little endian稱作“大尾”和“小尾”。
    2、字符編碼內碼,順帶介紹漢字編碼
    字符必須編碼後才能被計算機處理。計算機使用的缺省編碼方式就是計算機的內碼。早期的計算機使用7位的ASCII編碼,爲了處理漢字,程序員設計了用於簡體中文的GB2312和用於繁體中文的big5。
    GB2312(1980年)一共收錄了7445個字符,包括6763個漢字和682個其它符號。漢字區的內碼範圍高字節從B0-F7,低字節從A1-FE,佔用的碼位是72*94=6768。其中有5個空位是D7FA-D7FE。
    GB2312支持的漢字太少。1995年的漢字擴展規範GBK1.0收錄了21886個符號,它分爲漢字區和圖形符號區。漢字區包括21003個字符。2000年的GB18030是取代GBK1.0的正式國家標準。該標準收錄了27484個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。PC平臺必須支持GB18030,對嵌入式產品暫不作要求。所以手機、MP3一般只支持GB2312。
    從ASCII、GB2312、GBK到GB18030,這些編碼方法是向下兼容的,即同一個字符在這些方案中總是有相同的編碼,後面的標準支持更多的字符。在這些編碼中,英文和中文可以統一地處理。區分中文編碼的方法是高字節的最高位不爲0。按照程序員的稱呼,GB2312、GBK到GB18030都屬於雙字節字符集 (DBCS)。
    有的中文Windows的缺省內碼還是GBK,可以通過GB18030升級包升級到GB18030。不過GB18030相對GBK增加的字符,普通人是很難用到的,通常我們還是用GBK指代中文Windows內碼
    這裏還有一些細節:
    GB2312的原文還是區位碼,從區位碼到內碼,需要在高字節和低字節上分別加上A0。
    在DBCS中,GB內碼的存儲格式始終是big endian,即高位在前。
    GB2312的兩個字節的最高位都是1。但符合這個條件的碼位只有128*128=16384個。所以GBK和GB18030的低字節最高位都可能不是1。不過這不影響DBCS字符流的解析:在讀取DBCS字符流時,只要遇到高位爲1的字節,就可以將下兩個字節作爲一個雙字節編碼,而不用管低字節的高位是什麼。
    3、Unicode、UCS和UTF(UCS Transformation Format)
    前面提到從ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容(更準確地說,是與ISO-8859-1兼容),與GB碼不兼容。例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。
    UCS規定了怎麼用多個字節表示各種文字。而怎樣傳輸這些編碼,是由UTF(UCS Transformation Format)規範規定的!常見的UTF規範包括UTF-8、UTF-7、UTF-16。
    4、UTF的字節序和BOM
    UTF-8以字節爲編碼單元,沒有字節序的問題。UTF-16以兩個字節爲編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的字節序。例如收到一個“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節流“594E”,那麼這是“奎”還是“乙”?
    Unicode規範中推薦的標記字節順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:
    在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規範建議我們在傳輸字節流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。
    這樣如果接收者收到FEFF,就表明這個字節流是Big-Endian的;如果收到FFFE,就表明這個字節流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。
    UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗證一下)。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。
    Windows就是使用BOM來標記文本文件的編碼方式的。
    寫到這裏對編碼有了大致的瞭解了,就可以理解網上一些文章的話了,比如有一篇很流行的文章《URL編碼與SQL注射》裏面有一段是這麼說的:
    其實url編碼就是一個字符ascii碼的十六進制。不過稍微有些變動,需要在前面加上“%”。比如“\”,它的ascii碼是92,92的十六進制是5c,所以“\”的url編碼就是%5c。那麼漢字的url編碼呢?很簡單,看例子:“胡”的ascii碼是-17670,十六進制是BAFA,url編碼是“%BA%FA”。呵呵,知道怎麼轉換的了吧。
    這得從ASCII說起,擴展的ASCII字符集採用8bit255個字符顯然不夠用,於是各個國家紛紛制定了自己的文字編碼規範,其中中文的文字編碼規範叫做“GB2312-80”(就是GB2312),它是和ASCII兼容的一種編碼規範,其實就是用擴展ASCII沒有真正標準化這一點,把一箇中文字符用兩個擴展ASCII字符來表示。文中說的的中文ASCII碼實際上就是簡體中文的編碼2312GB!它把ASCII又擴充了一個字節,由於高位的第一位是0,所以會出現負數的形式,url編碼就是將漢字的這個GB2312編碼轉化成UTF-8的編碼並且每8位即一個字節前面加上%符號表示。
    那爲何UTF-8是進行網絡的規範傳輸編碼呢?
    在Unicode裏,所有的字符被一視同仁。漢字不再使用“兩個擴展ASCII”,而是使用“1個Unicode”,注意,漢字是“一個字符”了,於是,拆字、統計字數這些問題也就自然而然的解決了。但是,這個世界不是理想的,不可能在一夜之間所有的系統都使用Unicode來處理字符,所以Unicode在誕生之日,就必須考慮一個嚴峻的問題:和ASCII字符集之間的不兼容問題。
    我們知道,ASCII字符是單個字節的,比如“A”的ASCII是65。而Unicode是雙字節的,比如“A”的Unicode是0065,這就造成了一個非常大的問題:以前處理ASCII的那套機制不能被用來處理Unicode了
    另一個更加嚴重的問題是,C語言使用’\0’作爲字符串結尾,而Unicode裏恰恰有很多字符都有一個字節爲0,這樣一來,C語言的字符串函數將無法正常處理Unicode,除非把世界上所有用C寫的程序以及他們所用的函數庫全部換掉
    於是,比Unicode更偉大的東東誕生了,之所以說它更偉大是因爲它讓Unicode不再存在於紙上,而是真實的存在於我們大家的電腦中。那就是:UTF
    UTF= UCS Transformation Format UCS轉換格式,它是將Unicode編碼規則和計算機的實際編碼對應起來的一個規則。現在流行的UTF有2種:UTF-8和UTF-16
    其中UTF-16和上面提到的Unicode本身的編碼規範是一致的,這裏不多說了。而UTF-8不同,它定義了一種“區間規則”,這種規則可以和ASCII編碼保持最大程度的兼容,這樣做的好處是壓縮了字符西歐一些國家的內存消耗,減少了不必要的資源浪費,這在實際應用中是非常有必要的。
    UTF-8有點類似於Haffman編碼,它將Unicode編碼爲:
    7F的字符,用單個字節來表示;
    80-7FF的字符用兩個字節表示 (中文的編碼範圍)
    800-FFFF的字符用3字節表示
    因爲目前爲止Unicode-16規範沒有指定FFFF以上的字符,所以UTF-8最多是使用3個字節來表示一個字符。但理論上來說,UTF-8最多需要用6字節表示一個字符。
    在UTF-8裏,英文字符仍然跟ASCII編碼一樣,因此原先的函數庫可以繼續使用。而中文的編碼範圍是在0080-07FF之間,因此是2個字節表示(但這兩個字節和GB編碼的兩個字節是不同的)。
    看看編碼之多:ANSI,AscII,GB2312,GBK,BIG5,GB18030,Unicode,UCS(就是unicode)Utf-8,utf-16,utf-32 整整10種編碼~,算是夠複雜了
    可是這還僅僅是個開始,應用方面變化無窮。
    哦,漏了一個加密的base64編碼。
    什麼是Base64?
    按照RFC2045的定義,Base64被定義爲:Base64內容傳送編碼被設計用來把任意序列的8位字節描述爲一種不易被人直接識別的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
    爲什麼要使用Base64?
    在設計這個編碼的時候,我想設計人員最主要考慮了3個問題:
    1.是否加密?
    2.加密算法複雜程度和效率
    3.如何處理傳輸?
    加密是肯定的,但是加密的目的不是讓用戶發送非常安全的Email。這種加密方式主要就是“防君子不防小人”。即達到一眼望去完全看不出內容即可。
    基於這個目的加密算法的複雜程度和效率也就不能太大和太低。和上一個理由類似,MIME協議等用於發送Email的協議解決的是如何收發Email,而並不是如何安全的收發Email。因此算法的複雜程度要小,效率要高,否則因爲發送Email而大量佔用資源,路就有點走歪了。
    但是,如果是基於以上兩點,那麼我們使用最簡單的愷撒法即可,爲什麼Base64看起來要比愷撒法複雜呢?這是因爲在Email的傳送過程中,由於歷史原因,Email只被允許傳送ASCII字符,即一個8位字節的低7位。因此,如果您發送了一封帶有非ASCII字符(即字節的最高位是1)的Email通過有“歷史問題”的網關時就可能會出現問題。網關可能會把最高位置爲0!很明顯,問題就這樣產生了!因此,爲了能夠正常的傳送Email,這個問題就必須考慮!所以,單單靠改變字母的位置的愷撒之類的方案也就不行了。關於這一點可以參考RFC2046。
    基於以上的一些主要原因產生了Base64編碼。



發佈了9 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章