英文字母和中文漢字在不同字符集編碼中占用的字節數
字符占字節數,需要看編碼格式。
ANSI:英文占1個字節,中文占2個字節。
ASCII(128-255):英文占1個字節,中文占2個字節。
英文字母
字節數 : 1;編碼:GB2312
字節數 : 1;編碼:GBK
字節數 : 1;編碼:GB18030
字節數 : 1;編碼:ISO-8859-1
字節數 : 1;編碼:UTF-8
字節數 : 4;編碼:UTF-16
字節數 : 2;編碼:UTF-16BE
字節數 : 2;編碼:UTF-16LE
中文:
字節數 : 2;編碼:GB2312
字節數 : 2;編碼:GBK
字節數 : 2;編碼:GB18030
字節數 : 1;編碼:ISO-8859-1
字節數 : 2~4;編碼:UTF-8
字節數 : 4;編碼:UTF-16
字節數 : 2;編碼:UTF-16BE
字節數 : 2;編碼:UTF-16LE
發展歷史
從計算機字符編碼的發展歷史角度來看,大概經歷了三個階段:
第一階段:ASCII字符集和ASCII編碼
計算機剛開始只支持英語(即拉丁字符),其它語言不能夠在計算機上存儲和顯示。ASCII用一個字節(Byte)的7位(bit)表示一個字符,第一位置0。后來為了表示更多的歐洲常用字符又對ASCII進行了擴展,又有了EASCII,EASCII用8位表示一個字符,使它能多表示128個字符,支持了部分西歐字符。
第二階段:ANSI編碼(本地化)
為使計算機支持更多語言,通常使用 0x80~0xFF 范圍的2個字節來表示1個字符。比如:漢字 ‘中’ 在中文操作系統里,使用 [0xD6,0xD0] 這兩個字節存儲。不同的國家和地區制定了不同的標准,由此產生了 GB2312, BIG5, JIS 等各自的編碼標准。這些使用2個字節來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文操作系統下,ANSI 編碼代表 JIS 編碼。不同 ANSI 編碼之間互不兼容,當信息在國際間交流時,無法將屬於兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。
第三階段:UNICODE編碼(國際化)
為了使國際間信息交流更加方便,國際組織制定了 UNICODE 字符集,為各種語言中的每一個字符設定了統一並且唯一的數字編號,以滿足跨語言、跨平台進行文本轉換、處理的要求。UNICODE 常見的有三種編碼方式:UTF-8(1個字節表示)、UTF-16((2個字節表示))、UTF-32(4個字節表示)。
簡單歷史描述:
1.美國人首先對其英文字符進行了編碼,也就是最早的ASCII碼,用一個字節的第7位來表示英文的128個字符,高1位統一為0;
2.后來歐洲人發現尼瑪你這128位哪夠用,比如我高貴的法國人字母上面的還有注音符,這個怎么區分,得把高1位編進來吧,這樣歐洲普遍使用一個全字節進行編碼,最多可表示256位。歐美人就是喜歡直來直去,字符少,編碼用得位數少;
3.但是即使位數少,不同國家地區用不同的字符編碼,雖然0–127表示的符號是一樣的,但是128–255這一段的解釋完全亂套了,即使2進制完全一樣,表示的字符完全不一樣,比如135在法語,希伯來語,俄語編碼中完全是不同的符號;
4.更麻煩的是,電腦高科技傳到我們中國后,中國人發現我們有10萬多個漢字,你們歐美這256字塞牙縫都不夠。於是就發明了GB2312這些漢字編碼,典型的用2個字節來表示絕大部分的常用漢字,最多可以表示65536個漢字字符,這樣就不難理解有些漢字你在新華字典里查得到,但是電腦上如果不處理一下你是顯示不出來的了吧。
5.這下各用各的字符集編碼,這世界咋統一?俄國人發封Email給中國人,兩邊字符集編碼不同,尼瑪顯示都是亂碼啊。為了統一,於是就發明了Unicode,將世界上所有的符號都納入其中,每一個符號都給予一個獨一無二的編碼,現在Unicode可以容納100多萬個符號,每個符號的編碼都不一樣,這下可統一了,所有語言都可以互通,一個網頁頁面里可以同時顯示各國文字。
6.然而,Unicode雖然統一了全世界字符的二進制編碼,但沒有規定如何存儲啊親。x86和AMD體系結構的電腦小端序和大端序都分不清,別提計算機如何識別到底是Unicode還是ASCII了。如果Unicode統一規定,每個符號用三個或四個字節表示,那么每個英文字母前都必然有二到三個字節是0,文本文件的大小會因此大出兩三倍,這對於存儲來說是極大的浪費。這樣導致一個后果:出現了Unicode的多種存儲方式。
7.互聯網的興起,網頁上如果要顯示各種字符,就必須統一。UTF-8就是Unicode最重要的實現方式之一。另外還有UTF-16、UTF-32等。UTF-8不是固定字長編碼的,而是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。這是種比較巧妙的設計,如果一個字節的第一位是0,則這個字節單獨就是一個字符;如果第一位是1,則連續有多少個1,就表示當前字符占用多少個字節。
8.注意Unicode的字符編碼和UTF-8的存儲編碼表示是不同的,例如”嚴”字的Unicode碼是4E25,UTF-8編碼是E4B8A5,這個在7步驟里面做過解釋,UTF-8編碼不僅考慮了編碼,還考慮了存儲,E4B8A5是在存儲識別編碼的基礎上塞進了4E25。
9.UTF-8 使用一至四個字節為每個字符編碼。128 個ASCII字符(Unicode 范圍由 U+0000 至 U+007F)只需一個字節,帶有變音符號的拉丁文、希臘文、西里爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及馬爾代夫語(Unicode 范圍由 U+0080 至 U+07FF)需要二個字節,其他基本多文種平面(BMP)中的字符(CJK屬於此類)使用三個字節,其他 Unicode 輔助平面的字符使用四字節編碼。
10.最后,常規來看,中文漢字在UTF-8中到底占幾個字節:一般是3個字節,最常見的編碼方式是1110xxxx 10xxxxxx 10xxxxxx。
由ASCII發展而來的各個字符集和編碼的分支如下圖:
詳細內容
ASCII碼
我們知道,在計算機內部,所有信息最終都是一個二進制值。每一個二進制位(bit)有0和1兩種狀態,因此八個二進制位就可以組合出256種狀態,這被稱為一個字節(byte)。也就是說,一個字節一共可以用來表示256種不同的狀態,每一個狀態對應一個符號,就是256個符號,從00000000到11111111。
上個世紀60年代,美國制定了一套字符編碼,對英語字符與二進制位之間的關系,做了統一規定。這被稱為 ASCII 碼,一直沿用至今。
ASCII 碼一共規定了128個字符的編碼,比如空格SPACE是32(二進制00100000),大寫的字母A是65(二進制01000001)。這128個符號(包括32個不能打印出來的控制符號),只占用了一個字節的后面7位,最前面的一位統一規定為0。
二進制 | 十進制 | 十六進制 | 字符/縮寫 | 解釋 |
---|---|---|---|---|
00000000 | 0 | 00 | NUL (NULL) | 空字符 |
00000001 | 1 | 01 | SOH (Start Of Headling) | 標題開始 |
00000010 | 2 | 02 | STX (Start Of Text) | 正文開始 |
00000011 | 3 | 03 | ETX (End Of Text) | 正文結束 |
00000100 | 4 | 04 | EOT (End Of Transmission) | 傳輸結束 |
00000101 | 5 | 05 | ENQ (Enquiry) | 請求 |
00000110 | 6 | 06 | ACK (Acknowledge) | 回應/響應/收到通知 |
00000111 | 7 | 07 | BEL (Bell) | 響鈴 |
00001000 | 8 | 08 | BS (Backspace) | 退格 |
00001001 | 9 | 09 | HT (Horizontal Tab) | 水平制表符 |
00001010 | 10 | 0A | LF/NL(Line Feed/New Line) | 換行鍵 |
00001011 | 11 | 0B | VT (Vertical Tab) | 垂直制表符 |
00001100 | 12 | 0C | FF/NP (Form Feed/New Page) | 換頁鍵 |
00001101 | 13 | 0D | CR (Carriage Return) | 回車鍵 |
00001110 | 14 | 0E | SO (Shift Out) | 不用切換 |
00001111 | 15 | 0F | SI (Shift In) | 啟用切換 |
00010000 | 16 | 10 | DLE (Data Link Escape) | 數據鏈路轉義 |
00010001 | 17 | 11 | DC1/XON | |
00010010 | 18 | 12 | DC2 (Device Control 2) | 設備控制2 |
00010011 | 19 | 13 | DC3/XOFF | |
00010100 | 20 | 14 | DC4 (Device Control 4) | 設備控制4 |
00010101 | 21 | 15 | NAK (Negative Acknowledge) | 無響應/非正常響應/拒絕接收 |
00010110 | 22 | 16 | SYN (Synchronous Idle) | 同步空閑 |
00010111 | 23 | 17 | ETB (End of Transmission Block) | 傳輸塊結束/塊傳輸終止 |
00011000 | 24 | 18 | CAN (Cancel) | 取消 |
00011001 | 25 | 19 | EM (End of Medium) | 已到介質末端/介質存儲已滿/介質中斷 |
00011010 | 26 | 1A | SUB (Substitute) | 替補/替換 |
00011011 | 27 | 1B | ESC (Escape) | 逃離/取消 |
00011100 | 28 | 1C | FS (File Separator) | 文件分割符 |
00011101 | 29 | 1D | GS (Group Separator) | 組分隔符/分組符 |
00011110 | 30 | 1E | RS (Record Separator) | 記錄分離符 |
00011111 | 31 | 1F | US (Unit Separator) | 單元分隔符 |
00100000 | 32 | 20 | (Space) | 空格 |
00100001 | 33 | 21 | ! | |
00100010 | 34 | 22 | " | |
00100011 | 35 | 23 | # | |
00100100 | 36 | 24 | $ | |
00100101 | 37 | 25 | % | |
00100110 | 38 | 26 | & | |
00100111 | 39 | 27 | ' | |
00101000 | 40 | 28 | ( | |
00101001 | 41 | 29 | ) | |
00101010 | 42 | 2A | * | |
00101011 | 43 | 2B | + | |
00101100 | 44 | 2C | , | |
00101101 | 45 | 2D | - | |
00101110 | 46 | 2E | . | |
00101111 | 47 | 2F | / | |
00110000 | 48 | 30 | 0 | |
00110001 | 49 | 31 | 1 | |
00110010 | 50 | 32 | 2 | |
00110011 | 51 | 33 | 3 | |
00110100 | 52 | 34 | 4 | |
00110101 | 53 | 35 | 5 | |
00110110 | 54 | 36 | 6 | |
00110111 | 55 | 37 | 7 | |
00111000 | 56 | 38 | 8 | |
00111001 | 57 | 39 | 9 | |
00111010 | 58 | 3A | : | |
00111011 | 59 | 3B | ; | |
00111100 | 60 | 3C | < | |
00111101 | 61 | 3D | = | |
00111110 | 62 | 3E | > | |
00111111 | 63 | 3F | ? | |
01000000 | 64 | 40 | @ | |
01000001 | 65 | 41 | A | |
01000010 | 66 | 42 | B | |
01000011 | 67 | 43 | C | |
01000100 | 68 | 44 | D | |
01000101 | 69 | 45 | E | |
01000110 | 70 | 46 | F | |
01000111 | 71 | 47 | G | |
01001000 | 72 | 48 | H | |
01001001 | 73 | 49 | I | |
01001010 | 74 | 4A | J | |
01001011 | 75 | 4B | K | |
01001100 | 76 | 4C | L | |
01001101 | 77 | 4D | M | |
01001110 | 78 | 4E | N | |
01001111 | 79 | 4F | O | |
01010000 | 80 | 50 | P | |
01010001 | 81 | 51 | Q | |
01010010 | 82 | 52 | R | |
01010011 | 83 | 53 | S | |
01010100 | 84 | 54 | T | |
01010101 | 85 | 55 | U | |
01010110 | 86 | 56 | V | |
01010111 | 87 | 57 | W | |
01011000 | 88 | 58 | X | |
01011001 | 89 | 59 | Y | |
01011010 | 90 | 5A | Z | |
01011011 | 91 | 5B | [ | |
01011100 | 92 | 5C | \ | |
01011101 | 93 | 5D | ] | |
01011110 | 94 | 5E | ^ | |
01011111 | 95 | 5F | _ | |
01100000 | 96 | 60 | ` | |
01100001 | 97 | 61 | a | |
01100010 | 98 | 62 | b | |
01100011 | 99 | 63 | c | |
01100100 | 100 | 64 | d | |
01100101 | 101 | 65 | e | |
01100110 | 102 | 66 | f | |
01100111 | 103 | 67 | g | |
01101000 | 104 | 68 | h | |
01101001 | 105 | 69 | i | |
01101010 | 106 | 6A | j | |
01101011 | 107 | 6B | k | |
01101100 | 108 | 6C | l | |
01101101 | 109 | 6D | m | |
01101110 | 110 | 6E | n | |
01101111 | 111 | 6F | o | |
01110000 | 112 | 70 | p | |
01110001 | 113 | 71 | q | |
01110010 | 114 | 72 | r | |
01110011 | 115 | 73 | s | |
01110100 | 116 | 74 | t | |
01110101 | 117 | 75 | u | |
01110110 | 118 | 76 | v | |
01110111 | 119 | 77 | w | |
01111000 | 120 | 78 | x | |
01111001 | 121 | 79 | y | |
01111010 | 122 | 7A | z | |
01111011 | 123 | 7B | { | |
01111100 | 124 | 7C | ||
01111101 | 125 | 7D | } | |
01111110 | 126 | 7E | ~ | |
01111111 | 127 | 7F | DEL (Delete) | 刪除 |
備注:
數值 8、9、10 和 13 可以分別轉換為退格符、制表符、換行符和回車符。這些字符都沒有圖形表示,但是對於不同的應用程序,這些字符可能會影響文本的顯示效果。
非ASCII編碼
英語用128個符號編碼就夠了,但是用來表示其他語言,128個符號是不夠的。比如,在法語中,字母上方有注音符號,它就無法用 ASCII 碼表示。於是,一些歐洲國家就決定,利用字節中閑置的最高位編入新的符號。比如,法語中的é的編碼為130(二進制10000010)。這樣一來,這些歐洲國家使用的編碼體系,可以表示最多256個符號。但是,這里又出現了新的問題。不同的國家有不同的字母,因此,哪怕它們都使用256個符號的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (ג),在俄語編碼中又會代表另一個符號。但是不管怎樣,所有這些編碼方式中,0-127表示的符號是一樣的,不一樣的只是128-255的這一段。至於亞洲國家的文字,使用的符號就更多了,漢字就多達10萬左右。一個字節只能表示256種符號,肯定是不夠的,就必須使用多個字節表達一個符號。比如,簡體中文常見的編碼方式是 GB2312,使用兩個字節表示一個漢字,所以理論上最多可以表示 256 * 256 = 65536 個符號。
中文編碼的問題需要專文討論,這篇筆記不涉及。這里只指出,雖然都是用多個字節表示一個符號,但是GB類的漢字編碼與后文的 Unicode 和 UTF-8 是毫無關系的。
十進制 | 十六進制 | 字符 | 十進制 | 十六進制 | 字符 |
---|---|---|---|---|---|
128 | 0x80 | € | 160 | 0xA0 | [空格] |
129 | 0x81 | | 161 | 0xA1 | ¡ |
130 | 0x82 | ‚ | 162 | 0xA2 | ¢ |
131 | 0x83 | ƒ | 163 | 0xA3 | £ |
132 | 0x84 | „ | 164 | 0xA4 | ¤ |
133 | 0x85 | … | 165 | 0xA5 | ¥ |
134 | 0x86 | † | 166 | 0xA6 | ¦ |
135 | 0x87 | ‡ | 167 | 0xA7 | § |
136 | 0x88 | ˆ | 168 | 0xA8 | ¨ |
137 | 0x89 | ‰ | 169 | 0xA9 | © |
138 | 0x8A | Š | 170 | 0xAA | ª |
139 | 0x8B | ‹ | 171 | 0xAB | « |
140 | 0x8C | Œ | 172 | 0xAC | ¬ |
141 | 0x8D | | 173 | 0xAD | |
142 | 0x8E | Ž | 174 | 0xAE | ® |
143 | 0x8F | | 175 | 0xAF | ¯ |
144 | 0x90 | | 176 | 0xB0 | ° |
145 | 0x91 | ‘ | 177 | 0xB1 | ± |
146 | 0x92 | ’ | 178 | 0xB2 | ² |
147 | 0x93 | “ | 179 | 0xB3 | ³ |
148 | 0x94 | ” | 180 | 0xB4 | ´ |
149 | 0x95 | • | 181 | 0xB5 | µ |
150 | 0x96 | – | 182 | 0xB6 | ¶ |
151 | 0x97 | — | 183 | 0xB7 | · |
152 | 0x98 | ˜ | 184 | 0xB8 | ¸ |
153 | 0x99 | ™ | 185 | 0xB9 | ¹ |
154 | 0x9A | š | 186 | 0xBA | º |
155 | 0x9B | › | 187 | 0xBB | » |
156 | 0x9C | œ | 188 | 0xBC | ¼ |
157 | 0x9D | | 189 | 0xBD | ½ |
158 | 0x9E | ž | 190 | 0xBE | ¾ |
159 | 0x9F | Ÿ | 191 | 0xBF | ¿ |
十進制 | 十六進制 | 字符 | 十進制 | 十六進制 | 字符 |
---|---|---|---|---|---|
192 | 0xC0 | À | 224 | 0xE0 | à |
193 | 0xC1 | Á | 225 | 0xE1 | á |
194 | 0xC2 | Â | 226 | 0xE2 | â |
195 | 0xC3 | Ã | 227 | 0xE3 | ã |
196 | 0xC4 | Ä | 228 | 0xE4 | ä |
197 | 0xC5 | Å | 229 | 0xE5 | å |
198 | 0xC6 | Æ | 230 | 0xE6 | æ |
199 | 0xC7 | Ç | 231 | 0xE7 | ç |
200 | 0xC8 | È | 232 | 0xE8 | è |
201 | 0xC9 | É | 233 | 0xE9 | é |
202 | 0xCA | Ê | 234 | 0xEA | ê |
203 | 0xCB | Ë | 235 | 0xEB | ë |
204 | 0xCC | Ì | 236 | 0xEC | ì |
205 | 0xCD | Í | 237 | 0xED | í |
206 | 0xCE | Î | 238 | 0xEE | î |
207 | 0xCF | Ï | 239 | 0xEF | ï |
208 | 0xD0 | Ð | 240 | 0xF0 | ð |
209 | 0xD1 | Ñ | 241 | 0xF1 | ñ |
210 | 0xD2 | Ò | 242 | 0xF2 | ò |
211 | 0xD3 | Ó | 243 | 0xF3 | ó |
212 | 0xD4 | Ô | 244 | 0xF4 | ô |
213 | 0xD5 | Õ | 245 | 0xF5 | õ |
214 | 0xD6 | Ö | 246 | 0xF6 | ö |
215 | 0xD7 | × | 247 | 0xF7 | ÷ |
216 | 0xD8 | Ø | 248 | 0xF8 | ø |
217 | 0xD9 | Ù | 249 | 0xF9 | ù |
218 | 0xDA | Ú | 250 | 0xFA | ú |
219 | 0xDB | Û | 251 | 0xFB | û |
220 | 0xDC | Ü | 252 | 0xFC | ü |
221 | 0xDD | Ý | 253 | 0xFD | ý |
222 | 0xDE | Þ | 254 | 0xFE | þ |
223 | 0xDF | ß | 255 | 0xFF | ÿ |
Unicode編碼
世界上存在着多種編碼方式,同一個二進制數字可以被解釋成不同的符號。因此,要想打開一個文本文件,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。為什么電子郵件常常出現亂碼?就是因為發信人和收信人使用的編碼方式不一樣。可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,那么亂碼問題就會消失。這就是 Unicode,就像它的名字都表示的,這是一種所有符號的編碼。
Unicode 當然是一個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字嚴。具體的符號對應表,可以查詢unicode.org,或者專門的漢字對應表。
Unicode的問題
需要注意的是,Unicode 只是一個符號集,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。比如,漢字"嚴"的 Unicode 是十六進制數4E25,轉換成二進制數足足有15位(100111000100101),也就是說,這個符號的表示至少需要2個字節。表示其他更大的符號,可能需要3個字節或者4個字節,甚至更多。這里就有兩個嚴重的問題,第一個問題是,如何才能區別 Unicode 和 ASCII ?計算機怎么知道三個字節表示一個符號,而不是分別表示三個符號呢?第二個問題是,我們已經知道,英文字母只用一個字節表示就夠了,如果 Unicode 統一規定,每個符號用三個或四個字節表示,那么每個英文字母前都必然有二到三個字節是0,這對於存儲來說是極大的浪費,文本文件的大小會因此大出二三倍,這是無法接受的。
它們造成的結果是:
1.出現了 Unicode 的多種存儲方式,也就是說有許多種不同的二進制格式,可以用來表示 Unicode。
2.Unicode 在很長一段時間內無法推廣,直到互聯網的出現。
UTF-8
互聯網的普及,強烈要求出現一種統一的編碼方式。UTF-8 就是在互聯網上使用最廣的一種 Unicode 的實現方式。其他實現方式還包括 UTF-16(字符用兩個字節或四個字節表示)和 UTF-32(字符用四個字節表示),不過在互聯網上基本不用。重復一遍,這里的關系是,UTF-8 是 Unicode 的實現方式之一。UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。
UTF-8 的編碼規則很簡單,只有二條:
1.對於單字節的符號,字節的第一位設為0,后面7位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。
2.對於n字節的符號(n > 1),第一個字節的前n位都設為1,第n + 1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼。
下表總結了編碼規則,字母x表示可用編碼的位:
Unicode符號范圍 | UTF-8編碼方式
(十六進制) | (二進制)
--------------------+-------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
跟據上表,解讀 UTF-8 編碼非常簡單。如果一個字節的第一位是0,則這個字節單獨就是一個字符;如果第一位是1,則連續有多少個1,就表示當前字符占用多少個字節。
下面,還是以漢字"嚴"為例,演示如何實現 UTF-8 編碼。
嚴的 Unicode 是4E25(100111000100101),根據上表,可以發現4E25處在第三行的范圍內(0000 0800 - 0000 FFFF),因此嚴的 UTF-8 編碼需要三個字節,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,從嚴的最后一個二進制位開始,依次從后向前填入格式中的x,多出的位補0。這樣就得到了,嚴的 UTF-8 編碼是11100100 10111000 10100101,轉換成十六進制就是E4B8A5。
Unicode 與 UTF-8之間的轉換
通過以上的例子,可以看到嚴的 Unicode碼 是4E25,UTF-8 編碼是E4B8A5,兩者是不一樣的。它們之間的轉換可以通過程序實現。
Windows平台,有一個最簡單的轉化方法,就是使用內置的記事本小程序notepad.exe。打開文件后,點擊文件菜單中的另存為命令,會跳出一個對話框,在最底部有一個編碼的下拉條。
以下為Win10系統記事本截圖
里面有五個選項:ANSI,UTF-16LE,UTF-16BE和UTF-8及帶BOM的UTF-8。
- ANSI是默認的編碼方式。對於英文文件是ASCII編碼,對於簡體中文文件是GB2312編碼(只針對 Windows 簡體中文版,如果是繁體中文版會采用 Big5 碼)。
- UTF-16LE其后綴是 LE 即 little-endian,小端的意思。小端就是將高位的字節放在高地址表示。
- UTF-16BE其后綴是 BE 即 big-endian,大端的意思。大端就是將高位的字節放在低地址表示。
- UTF-8編碼,也就是以上談到的編碼方法。
- UTF-8 BOM又叫UTF-8 簽名,UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。當文本程序讀取到以 EF BB BF開頭的字節流時,就知道這是UTF-8編碼了。Windows就是使用BOM來標記文本文件的編碼方式的。
選擇完"編碼方式"后,點擊"保存"按鈕,文件的編碼方式就立刻轉換好了。
在計算機內存中,統一使用Unicode編碼,當需要保存到硬盤或者需要傳輸的時候,就轉換為UTF-8編碼。
擴展:
Unicode的學名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。在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(即Byte Order Mark)。
LE(Little Endian) 和 BE(Big Endian)
UCS-2 格式可以存儲 Unicode 碼(碼點不超過0xFFFF)。以漢字嚴為例,Unicode 碼是4E25,需要用兩個字節存儲,一個字節是4E,另一個字節是25。存儲的時候,4E在前,25在后,這就是 Big endian 方式;25在前,4E在后,這是 Little endian 方式。
這兩個古怪的名稱來自英國作家斯威夫特的《格列佛游記》。在該書中,小人國里爆發了內戰,戰爭起因是人們爭論,吃雞蛋時究竟是從大頭(Big-endian)敲開還是從小頭(Little-endian)敲開。為了這件事情,前后爆發了六次戰爭,一個皇帝送了命,另一個皇帝丟了王位。
第一個字節在前,就是"大頭方式"(Big endian),第二個字節在前就是"小頭方式"(Little endian)。
那么很自然的,就會出現一個問題:計算機怎么知道某一個文件到底采用哪一種方式編碼?
Unicode 規范定義,每一個文件的最前面分別加入一個表示編碼順序的字符,這個字符的名字叫做"零寬度非換行空格"(zero width no-break space),用FEFF表示。這正好是兩個字節,而且FF比FE大1。如果一個文本文件的頭兩個字節是FE FF,就表示該文件采用大頭方式;如果頭兩個字節是FF FE,就表示該文件采用小頭方式。
BOM格式編碼
BOM(Byte Order Mark),是UTF編碼方案里用於標識編碼的標准標記。
UTF編碼 ║ Byte Order Mark
UTF-8 ║ EF BB BF
UTF-16LE ║ FF FE
UTF-16BE ║ FE FF
UTF-32LE ║ FF FE 00 00
UTF-32BE ║ 00 00 FE FF
在UTF-16里本來是FF FE,變成UTF-8就成了EF BB BF。這個標記是可選的,因為UTF8字節沒有順序,所以它可以被用來檢測一個字節流是否是UTF-8編碼的。
微軟做這種檢測,但有些軟件不做這種檢測, 而把它當作正常字符處理。
這個BOM頭只是建議添加,不是強制的,所以不少軟件和系統沒有添加這個BOM頭(所以有些軟件格式中有帶BOM頭和NoBOM頭的選擇)
總結
UTF-8,UTF-16,UTF-32的區別:
-
UTF-8為可變長的編碼方式,根據不同的符號而變化字節長度,節省存儲空間
-
UTF-16奇葩,使用 2 個或者 4 個字節來存儲
-
UTF-32固定為4個字節,直接存儲 Unicode 編號即可,不需要任何編碼轉換。浪費了空間,提高了效率。
只有 UTF-8 兼容 ASCII,UTF-16 和 UTF-32 都不兼容 ASCII,因為它們沒有單字節編碼。
摘要:
摘自:https://www.cnblogs.com/hongdada/p/9901246.html
作者:hongdada