站長資訊網
        最全最豐富的資訊網站

        關于Windows Notepad里可選的字符編碼

        下面由notepad教程欄目給大家介紹關于Windows Notepad里可選的字符編碼,希望對需要的朋友有所幫助!

        關于Windows Notepad里可選的字符編碼

        簡析Windows Notepad里可選的字符編碼

        這篇文章就簡單測試一下Windows Notepad的行為。

        關于Windows Notepad里可選的字符編碼

        ▲ Windows Notepad的編碼包含ANSI、Unicode、Unicode big endian和UTF-8。

        警告

        本文僅僅闡述一個廣泛使用的軟件的技術事實,不代表作者支持或反對使用該軟件。
        事實上作者推薦任何時候都不使用 Windows Notepad 來處理計算機程序代碼。
        本文僅在某一個簡體中文版64位Windows 7的實例下驗證,僅供參考。不保證在其他相同或相異系統下能夠重現一致的結果。

        注意

        本文嚴格區分Unicode的編碼字節序列化
        Unicode的編碼僅指使用數(通常寫成16進制數)來一對一的代表字符的工作。這個數的范圍僅受Unicode標準的約束,與計算機毫無關聯。
        Unicode的字節序列化指為了能夠寫入計算機存儲器,而把一個Unicode標準范圍內的數,表示成N個字節的工作。

        測試用例

        測試用例為:“錕斤拷【斷行】a【斷行】”。(錕斤拷是一種信仰。)

        所有字符的GBK和Unicode編碼為:

        • 錕 GBK=EFBF Unicode=U+951F
        • 斤 GBK=BDEF Unicode=U+65A4
        • 拷 GBK=BFBD Unicode=U+62F7

        以下ASCII字符的GBK和Unicode編碼與ASCII一致:

        a=0x61 CR=0x0D LF=0x0A
        (Windows一個換行符占有兩個字符:CR+LF)

        ANSI

        在簡體中文系統下,ANSI就是中華人民共和國國家標準定義的GBK編碼。

        Windows Notepad使用ANSI存儲這個文件的結果如下:

        EF BF  BD EF  BF BD  0D  0A  61  0D  0A -----  -----  -----  --  --  --  --  --

        簡單的使用GBK編碼存儲了所有的字符。最高位不是1的單字節并等同于ASCII,否則雙字節。

        這里要注意字節序(Endian)的問題[注A]。可以看到這里的字節序是大端在先(big-endian)的。

        但是不必特意強調“大端在先的GBK”——因為從GB2312開始,標準就規定了存儲方式是大端在先的[注B]。后來的GBK和GB18030-2000向下兼容。

        ANSI的麻煩就是依賴系統——其他語言系統的ANSI就不是GBK了,打開GBK的文件必然亂碼。并且GBK的字符集本身也太小。
        (千萬不要說“我只用中文”——少了Unicode那些符號,網上那些顏文字都打不出來)

        Unicode系列

        Windows Notepad所說的“Unicode”、“Unicode big endian”和UTF-8,全都是同樣的Unicode編碼的不同的字節序列化存儲方法。

        UTF-16 和 BOM

        這里的Unicode指UTF-16[注C]。UTF-16是極其簡單粗暴的序列化方法——絕大多數的Unicode字符都在U+0000~U+FFFF的范圍內[注D],那就每個字符用兩個字節,把Unicode編碼的原始值寫盤。

        注意ASCII字符也必須浪費一倍的空間存儲高8位的0x00——因為如果把高8位的0略了,解析時就再也沒有其他的依據去斷字。

        對于UTF-16就存在大端和小端的問題了——UTF-16并不規定字節的大端在前還是小端在前。但UTF-16并不包含表示字節序的信息,總不能人工看看哪個解析是不亂碼的吧……

        Unicode提供的解決方式是,把一個零寬無斷字空格符U+FEFF ZERO WIDTH NO-BREAK SPACE)以UTF-16的方式序列化之后,塞到文件的最前邊。這樣UTF-16解析器讀取文件的前兩個字節,如果是FE FF就是大端在前,FF FE就是小端在前。

        這個塞進去的東西就叫BOM(Byte Order Mark,字節順序標記)。

        值得一提的是,零寬無斷字空格符也常用于充當1個有效字符,破拆各種場合的字數限制。包括SegmentFault的問答和評論內容在內。

        記事本的“Unicode”和“Unicode big endian”

        單寫“Unicode”,根本就不是一種存儲方法的完整表達。因為這只包含編碼而沒有字節序列化

        M$出現這種錯誤,我一點都不覺得奇怪。死記結論就可以了:Windows Notepad的“Unicode”就是UTF-16

        Windows Notepad使用“Unicode” = 小端在先的UTF-16,存儲這個文件的結果如下:

         FF FE 1F 95 A4 65 F7 62 0D 00 0A 00 61 00 0D 00 0A 00  -BOM- ----- ----- ----- ----- ----- ----- ----- -----  U+FEFF  951F  65A4  62F7  000D  000A  0061  000D  000A <--Unicode原始值

        Windows Notepad使用“Unicode big endian” = 大端在先的UTF-16,存儲這個文件的結果如下:

         FE FF 95 1F 65 A4 62 F7 00 0D 00 0A 00 61 00 0D 00 0A  -BOM- ----- ----- ----- ----- ----- ----- ----- -----  U+FEFF  951F  65A4  62F7  000D  000A  0061  000D  000A <--Unicode原始值

        UTF-8

        UTF-8是一種用1~4個字節表示1個Unicode字符的變長的字節序列化方法。具體的實現細節看這篇文章。UTF-8的好處在于:

        1. 無論是IETF的推薦,還是實際業界的執行,UTF-8都是互聯網的標準。
        2. 向下兼容,ASCII字符UTF-8序列化后仍是原樣,任何ASCII文件也是有效的UTF-8文件。
        3. 沒有字節序問題。UTF-8的字節序是由RFC3629定死的。

        Windows Notepad使用UTF-8存儲這個文件的結果如下:

         EF BB BF  E9 94 9F  E6 96 A4  E6 8B B7  0D   0A   61   0D   0A  --BOM---  --------  --------  --------  --   --   --   --   -- U+ FEFF      951F      65A4      62F7   000D 000A 0061 000D 000A <--Unicode原始值

        注意UTF-8前邊仍然塞進去了U+FEFF按照UTF-8序列化的結果EF BB BF,作為前邊提到過的BOM字節順序標記。Windows Notepad存儲的UTF-8,是帶有BOM標記的UTF-8

        但是如果僅僅對于UTF-8而言,字節序是沒有意義的。因為UTF-8的字節序被規范寫死,U+FEFF編碼后必然得到EF BB FF,得不出其他的。沒有二義性,BOM就失去了原本的意義。也許只有區別UTF-8文件和UTF-16文件的用處……

        如何對待UTF-8文件的BOM,RFC3629的第6章有詳細的規定,不加詳述。

        值得一提的是,BOM我想很多PHP程序員都經歷過并且恨之入骨——PHP不認識文件中的BOM頭并會將其作為HTTP Response的正文送出。這甚至在無緩沖的情況下,會導致header()等必須在Response開始前執行的函數直接失效。

        所以PHP程序員總是會喜歡UTF-8 without BOM的編碼方式——這基本也就宣布了Windows下的PHP開發,Windows Notepad完全的淘汰出局,哪怕是任何一星半點代碼的臨時修改。

        番外:Notepad++的字符編碼測試

        ANSI沒有區別,但Notepad++支持選擇多國編碼的不同ANSI編碼方式(類似瀏覽器里選編碼),可以輕松生成或讀取Shift-JIS等其他字符集的文件。適合用于對付日文老游戲的README等文檔。

        UCS-2 Big Endian、UCS-2 Little Endian和前邊UTF-16的兩個例子一致。注意UTF-16的文件不提供“無BOM”的存儲方法(提供了就壞了)。

        UTF-8仍然代表“帶有BOM標記的UTF-8”。但同時提供PHP程序員最愛的UTF-8 without BOM,就像:

         E9 94 9F  E6 96 A4  E6 8B B7  0D   0A   61   0D   0A  --------  --------  --------  --   --   --   --   -- U+ 951F      65A4      62F7   000D 000A 0061 000D 000A <--Unicode原始值

        Simple and clean.

        注解
        [注A] 對于一個雙(多)字節的數,一定會按8位截斷為1字節后寫盤。那么寫盤時先寫最低8位還是先寫最高8位,就是所謂的“字節序”(Endian)問題。例如,數0x01020304寫盤時,是先寫最低8位的04 03 02 01,還是先寫最高8位的01 02 03 04
        先寫低8位的叫做小端在先(little-endian),先寫高8位的叫做大端在先(big-endian)。實際采用何種字節序受系統環境、標準規范和軟件實際編寫的多方面控制,不一概而論。
        [注B] 字節序如果我沒弄錯,是GB2312采用的EUC字符編碼方法控制的。
        [注C] 本文并不嚴格區分UTF-16UCS-2
        [注D] Unicode的最大值實際上達到了U+10FFFF,超出了兩個字節能夠存儲的限度。
        但Unicode由于歷史原因,留下了U+D800~U+DFFF這一段永久保留不用的空缺區域。
        因此對U+10000及以上的字符,UTF-16借助了這部分空缺區域,對這些編碼超大的字符打破2字節16位的慣例,特別的用4字節32位去表示之。
        這一部分編碼值太大的字符,超出了GBK的字符集范圍,因此本文將完全忽略。如有機會再進一步測試。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 欧美人与性动交α欧美精品成人色XXXX视频 | 四虎成人www国产精品| 国产亚洲精品a在线无码| 国产精品区免费视频| 精品国产品香蕉在线观看75| 亚洲人成亚洲精品| 精品国产sm捆绑最大网免费站| 久久精品中文字幕第23页| 久久精品欧美日韩精品| 精品国产麻豆免费人成网站| 久久久无码精品亚洲日韩按摩| 秋霞久久国产精品电影院| 精品久久国产一区二区三区香蕉 | www.精品| 亚洲精品制服丝袜四区| 99re这里只有精品6| 国产精品成人国产乱一区| 亚洲国产综合精品一区在线播放| 久久Av无码精品人妻系列| 亚洲欧美日韩精品久久亚洲区| 国产精品18久久久久久vr| 国产精品自在线拍国产手机版| 亚洲av午夜成人片精品网站| 欧美精品福利视频| 国产精品一区二区不卡| 成人区精品一区二区不卡 | 国产一区二区三精品久久久无广告| 伊人久久无码精品中文字幕| 精品久久久久一区二区三区 | 中文字幕精品一区二区三区视频| 青青青青久久精品国产h久久精品五福影院1421 | 久久婷婷国产综合精品| 四虎影视永久在线观看精品| 亚洲国产精品国自产拍AV| 亚洲国产精品无码中文字| 亚洲AV乱码久久精品蜜桃| 久久亚洲私人国产精品| 国产精品无码无在线观看| 99在线精品视频| 91精品国产品国语在线不卡| 亚洲日韩国产精品第一页一区|