int i = 'a’;//i=97
為什么'a'對應的十進制是97
計算機是以二進制的形式來存儲數據的,它只認識 0 和 1 兩個數字,我們在屏幕上看到的文字,在存儲之前都被轉換成了二進制(0和1序列)(編碼),在顯示時也要根據二進制找到對應的字符。(解碼)
字符集定義了文字和二進制的對應關系,為字符分配了唯一的編碼
如ASCII字符集定義的'a'對應的編碼是01100001
字符集規定了某個文字對應的二進制數字存放方式(編碼)和某串二進制數值代表了哪個文字(解碼)的轉換關系。
字符集只是一個規則集合的名字,對應到真實生活中,字符集就是對某種語言的稱呼。例如:英語,漢語。
對于一個字符集來說要正確編碼轉碼一個字符需要三個關鍵元素:字庫表(character repertoire)、編碼字符集(coded character set)、字符編碼(character encoding form)。
計算機是美國人發明的,他們首先要考慮的問題是,如何將二進制和英文字母對應起來。
當時,各個廠家或者公司都有自己的做法,編碼規則并不統一,這給不同計算機之間的數據交換帶來不小的麻煩。但是相對來說,能夠得到普遍認可的有 IBM 發明的 EBCDIC 和此處要談的 ASCII。
ASCII 是“American Standard Code for Information Interchange”的縮寫,翻譯過來是“美國信息交換標準代碼”??催@個名字就知道,這套編碼是美國人給自己設計的,他們并沒有考慮歐洲那些擴展的拉丁字母,也沒有考慮韓語和日語,我大中華幾萬個漢字更是不可能被重視。
ASCII 的標準版本于 1967 年第一次發布,最后一次更新則是在 1986 年,迄今為止共收錄了 128 個字符,包含了基本的拉丁字母(英文字母)、阿拉伯數字(也就是 1234567890)、標點符號(,.!
等)、特殊符號(@#$%^&
等)以及一些具有控制功能的字符(往往不會顯示出來)。
在 ASCII 編碼中,大寫字母、小寫字母和阿拉伯數字都是連續分布的(見下表),這給程序設計帶來了很大的方便。例如要判斷一個字符是否是大寫字母,就可以判斷該字符的 ASCII 編碼值是否在 65~90 的范圍內。
字庫表
二進制 | 十進制 | 十六進制 | 字符/縮寫 | 解釋 |
---|---|---|---|---|
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 (Device Control 1/Transmission On) | 設備控制1/傳輸開始 |
00010010 | 18 | 12 | DC2 (Device Control 2) | 設備控制2 |
00010011 | 19 | 13 | DC3/XOFF (Device Control 3/Transmission Off) | 設備控制3/傳輸中斷 |
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) | 刪除 |
后來歐洲又在ASCII碼基礎上擴充有了ISO-8859-1
國人也需要將中文存儲到計算機,規定了GB2312字符集,使用2個字節表示一個漢字,英文還是1個字節同上
那么存儲時好存,找到字符對應字符編碼存儲即可,但讀取時怎么知道是按一個字節讀還是2個字節讀
如101110011111101001100001
,凡是漢字,對應字符編碼都以1開頭,所以讀取2個字節1011100111111010
即國,以0開頭,讀取1個字節,01100001
即a
GB2312 編碼范圍, GB2312 編碼表 (qqxiuzi.cn)
分為94個區,每個區有94個數,下面以16進制表示
常見進制加減法二進制、八進制、十六進制、十進制之間的轉換
GB2312編碼范圍:A1A1-FEFE,其中漢字編碼范圍:B0A1-F7FE。
如、的序號是A1A2,前兩位是區號,后兩位是區中的第幾個數
如A1A2代表01區的第2個數
那么反過來呢?
以包為例,它在16區的第92個數,把它們轉成16進制分別與A0相加
16轉成十六進制是1092轉成十六進制是5C 10+ A0 = B0 5C+ A0= FC即包對應的序號是B0FC,轉成2進制是1011000011111100,當作字符編碼存儲
E5A4代表什么 E5- A0= 45 A4- A0= 445轉成10進制是69,4轉成10進制還是4即69區的第4個數
如果10轉16進制看著不舒服
GB2312 中文簡體字庫表_panqihe的專欄-CSDN博客_gb2312字庫表
、對應的是A1A0+2,即A1A2,比較一目了然
GBK和GB18030是后來的擴展編碼
GB2312,GBK,GB18030 這幾種字符集的主要區別是什么
早期人們用 8 位二進制來編碼英文字母(最前面的一位是 0),也就是說,將英文字母和一些常用的字符和這 128 中二進制 0、1 串一一對應起來,比如說 大寫字母“A”所對應的二進制位“01000001”,轉換為十六進制為 41。
在美國,這 128 是夠了,但是其他國家不答應啊,他們的字符和英文是有出入的,比如在法語中在字母上有注音符號,如 é ,這個怎么表示成二進制?
所以各個國家就決定把字節中最前面未使用的那一個位拿來使用,原來的 128 種狀態就變成了 256 種狀態,比如 é 就被編碼成 130(二進制的 10000010)。
為了保持與 ASCII 碼的兼容性,一般最高為為 0 時和原來的 ASCII 碼相同,最高位為 1 的時候,各個國家自己給后面的位 (1xxx xxxx) 賦予他們國家的字符意義。
但是這樣一來又有問題出現了,不同國家對新增的 128 個數字賦予了不同的含義,比如說 130 在法語中代表了 é,但是在希伯來語中卻代表了字母 Gimel(這不是希伯來字母,只是讀音翻譯成英文的形式)具體的希伯來字母 Gimel 看下圖
所以這就成了不同國家有不同國家的編碼方式,所以如果外國朋友發給你一封郵件,打開后全是???亂碼,正是因為使用的解碼方式與編碼不一致
如下面的例子
使用UTF-8編碼(一個漢字占3個字節)儲存"天下"得到的二進制是11100101 10100100 10101001 11100100 10111000 10001011
使用GB2312解碼,1開頭的讀2個字節,11100101 10100100
轉成16進制是E5A4,即69區的第4個數澶,剩下自己解析,即“澶╀笅”
Unicode 是為了解決傳統的字符編碼方案的局限而產生的,它為每種語言中的每個字符設定了統一并且唯一的序號,這個序號一般寫成 16 進制,在前面加上 U+。例如:“馬”的 Unicode 是U+9A6C。
Unicode 本身只規定了每個字符的在表上的編號是多少(編碼字符集),并沒有規定這個編號如何存
那我可以直接把 Unicode 編號直接轉換成二進制進行存儲,就同ASCII和GBK一樣,是的,你可以,但是這個就需要人為的規定了,而 Unicode 并沒有說這樣弄,因為除了你這種直接轉換成二進制的方案外,還有其他方案,接下來我們會逐一看到。
編號怎么對應到二進制表示呢?有多種方案:主要有 UTF-8,UTF-16,UTF-32。
UCS-2和UCS-4是什么
先來看簡單的 UTF-32,很浪費空間
這個就是字符所對應編號的整數二進制形式,四個字節。這個就是直接轉換。 比如馬的 Unicode 為:U+9A6C,那么直接轉化為二進制,它的表示就為:00000000 00000000 10011010 01101100。
這里需要說明的是,轉換成二進制后計算機存儲的問題,我們知道,計算機在存儲器中排列字節有兩種方式:大端法和小端法,大端法就是將高位字節放到低地址處,比如16進制 0x1234, 計算機用兩個字節存儲,一個是高位字節 0x12,一個是低位字節 0x34,它的存儲方式為下:
計算機存儲的大端法和小端法
143416對應的二進制是00010100 00110100
,14是高位,34是低位字節;但16位不能放在1個只能裝8位的格子里,|00010100|00110100|
,高位字節放在前面叫大端法
|00110100|00010100
,這么放叫小端法
UTF-32 用四個字節表示,處理單元為四個字節(一次拿到四個字節進行處理),如果不分大小端的話,那么就會出現解讀錯誤,比如我們一次要處理四個字節 12 34 56 78,這四個字節是表示 0x12 34 56 78 還是表示 0x78 56 34 12?不同的解釋最終表示的值不一樣。
我們可以根據他們高低字節的存儲位置來判斷他們所代表的含義,所以在編碼方式中有 UTF-32BE 和 UTF-32LE,分別對應大端和小端,來正確地解釋多個字節(這里是四個字節)的含義。
0x11是什么,0x代表16進制的11
//可是試試輸出aint a = 11;//十進制a = 015;//八進制,相當于10進制的13a = 0x20;//16進制,10進制的32a = 0b11;//2進制,10進制的3
UTF-16 使用變長字節表示
① 對于編號在 U+0000 到 U+FFFF 的字符(常用字符集),直接用兩個字節表示。
② 編號在 U+10000 到 U+10FFFF 之間的字符,需要用四個字節表示。
同樣,UTF-16 也有字節的順序問題(大小端),所以就有 UTF-16BE 表示大端,UTF-16LE 表示小端。
1個16進制數對應4個二進制數位,2個16進制數位對應8個二進制數位,即1個字節
892316 -> 10001001 001000112
8916 -> 100010012
2316 -> 001000112
816 -> 10002
916 -> 10012
216 -> 00102
316 -> 00112
存儲a的二進制,a -> 009710 -> 006116
大端00000000 01100001
小端01100001 00000000
UTF-8 就是使用變長字節表示,顧名思義,就是使用的字節數可變,這個變化是根據 Unicode 編號的大小有關,編號小的使用的字節就少,編號大的使用的字節就多。使用的字節個數從 1 到 4 個不等。
UTF-8 的編碼規則是:
① 對于單字節的符號,字節的第一位設為 0,后面的7位為這個符號的 Unicode 碼,因此對于英文字母,UTF-8 編碼和 ASCII 碼是相同的。
② 對于n字節的符號(n>1),第一個字節的前 n 位都設為 1,第 n+1 位設為 0,后面字節的前兩位一律設為 10,剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼 。
舉個例子:比如說一個字符的 Unicode 編碼是 130,顯然按照 UTF-8 的規則一個字節是表示不了它(因為如果是一個字節的話前面的一位必須是 0),所以需要兩個字節(n = 2)。
根據規則,第一個字節的前 2 位都設為 1,第 3(2+1) 位設為 0,則第一個字節為:110X XXXX,后面字節的前兩位一律設為 10,后面只剩下一個字節,所以后面的字節為:10XX XXXX。
所以它的格式為 110XXXXX 10XXXXXX 。
下面我們來具體看看具體的 Unicode 編號范圍與對應的 UTF-8 二進制格式
那么對于一個具體的 Unicode 編號,具體怎么進行 UTF-8 的編碼呢?
首先找到該 Unicode 編號所在的編號范圍,進而可以找到與之對應的二進制格式,然后將該 Unicode 編號轉化為二進制數(去掉高位的 0),最后將該二進制數從右向左依次填入二進制格式的 X 中,如果還有 X 未填,則設為 0 。
比如:“馬”的 Unicode 編號是:0x9A6C,整數編號是 39532,對應第三個范圍(2048 - 65535),其格式為:1110XXXX 10XXXXXX 10XXXXXX,39532 對應的二進制是 1001 1010 0110 1100,將二進制填入進入就為:
11101001 10101001 10101100 。
關于“為何Unicode中文字符占取2個字節,而 UTF-8卻占3個字節”的網絡解釋修正
由于 UTF-8 的處理單元為一個字節(也就是一次處理一個字節),所以處理器在處理的時候就不需要考慮這一個字節的存儲是在高位還是在低位,直接拿到這個字節進行處理就行了,因為大小端是針對大于一個字節的數的存儲問題而言的。
綜上所述,UTF-8、UTF-16、UTF-32 都是 Unicode 的一種實現。
BOM:byte order mark,定義字節順序,因為網絡傳輸中分為兩種,大頭和小頭。uft-8不需要bom表明字節順序,但可以用BOM來表示編碼方式,windows就是采用bom來標記文本文件的編碼方式的。
bom是為utf-16和utf-32準備的,用于標記字節順序。微軟在utf-8中使用bom是因為這樣可以把UTF-8和ASCII等編碼區分開來,但這樣的文件在windows之外的操作系統里會帶來問題。
不含bom的UTF-8才是標準形式。UTF-8」和「帶 BOM 的 UTF-8」的區別就是有沒有 BOM。即文件開頭有沒有 U+FEFF。
UTF-8 的網頁代碼不應使用 BOM,否則常常會出錯。
那既然字庫表中的每一個字符都有一個自己的序號,直接把序號轉成二進制作為存儲內容就好了。為什么unicode還要多此一舉通過字符編碼把序號轉換成另外一種存儲格式呢?你看ASCII碼為什么不這樣?
其實原因也比較容易理解:unicode的目的是為了能夠涵蓋世界上所有的字符,準備了一個很大的字庫表,能夠裝下1114112個字符,比如最后一個字符對應的序號轉成的二進制是100001111111111111111至少占3個字節
但實際使用過程中會發現真正用的上的字符相對整個字庫表來說比例非常低。例如中文地區的程序幾乎不會需要日語字符,而一些英語國家甚至簡單的ASCII字庫表就能滿足基本需求。
而如果把每個字符都用字庫表中的序號轉成的二進制來存儲的話,每個字符就需要3個字節(這里以Unicode字庫為例),這樣對于原本用僅占一個字符的ASCII編碼的英語地區國家顯然是一個額外成本(存儲體積是原來的三倍)。算的直接一些,同樣一塊硬盤,用ASCII可以存1500篇文章,而用3字節Unicode序號存儲只能存500篇。于是就出現了UTF-8這樣的變長編碼。在UTF-8編碼中原本只需要一個字節的ASCII字符,仍然只占一個字節。而像中文及日語這樣的復雜字符就需要2個到3個字節來存儲。
java文件的編碼方式可能有多種多樣,但java編譯器只要指定了源文件的編碼方式,會自動按照java文件的編碼格式正確讀取后產生class文件,這里的class文件編碼是UTF-16BE編碼。
JVM加載class文件讀取時候使用Unicode編碼方式正確讀取class文件,那么原來定義的String s="漢字";在內存中的表現形式是Unicode編碼,UTF-16表示漢字只需2個字節,char類型剛好裝得下;要是使用UTF-8就不一定了
不管在編譯前java文件使用何種編碼,在編譯后成class后,他們都是一樣的----Unicode編碼表示。
char c = 'a’;a的字符編碼是00000000 01100001轉成int類型展現10進制的數,即97int i = c;//i=97 天的utf-16BE編碼是0101100100101001,對應16進制是5929c = 0x5929;//打印c結果是天
java常見的轉義字符
一般使用\開頭,把一個字符轉義
\n : 換行
\t : 制表符tab
\r : 換行
\f : 換頁
\u: 把16進制的編碼轉成對應的字符
char c = '\n';System.out.println(c);System.out.println(2);可以看到2前面多了一行空白行其實ln表示當前行結束打印,要繼續打印就要到下一行,不信把ln去掉 System.out.print(2);System.out.print(2);
System.out.print("s"+'\t'+2);可以看到s與2隔了一個tab鍵的距離
以天的16進制為例,5929char c = '\u5929';//c='天'
怎么輸出一個','是有特殊含義的字符,代表字符的開始char c = '\'';//使用\代表'是一個普通的字符
同理想輸出一個\char c = '\\';
轉載自十分鐘搞清字符集和字符編碼Unicode與UTF-8的區別Java java采用的編碼、JVM平臺默認字符集和外部資源的編碼utf-8與帶有BOM的utf-8的區別UTF-8的BOM是什么意思計算機中編碼方式---ASCII,ISO-8859-1以及UTF-8和UTF-16編碼計算機中編碼方式---ASCII,ISO-8859-1以及UTF-8和UTF-16編碼
本文來自那么簡潔的博客園,作者:赤北,轉載請注明原文鏈接:https://www.cnblogs.com/cqhh/p/15181487.html
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
北京西站換乘火車最晚買票時間?北京西站24小時售票,買票沒有最晚時間。開車前提前五分鐘停止檢票上車就行了。如果在北京西站換車,網上買票,不需要出站,省去了來回拖行李。直接檢票上車。北京西站售票廳營業時間?北京西站售票處24小時開放。工作人員24小時輪班,但是售票窗口晚上不像白天那么開放。北京西站共設91個售票窗口,分別位于車站北大廳南大廳地下一層和二層。在此基礎上,車站在南北廣場東西售票廳北二層入...
一萬日元等于多少?根據銀行外匯牌價數據(2018年10月9日):100日元對匯率中間價為6.1055,即1萬日元等于610.55元。日本100元是多少錢?和日元的匯率是一元,大約是二十日元。我們用這個匯率來算一下100日元可以換多少。100除以20得5,所以換成就是5元。日本100元是多少錢?匯率轉換100日元大約等于5.0466元日元(日語:日語,romaji: en,英語:Yen),其紙幣稱為...
TRENDnet是一個什么公司?TRENDnet:趨勢技術、網絡安全軟件和服務的全球領導者。TRENDnet總部位于日本東京和美國硅谷,分別在日本東京證券交易所和美國納斯達克上市。它分別于2002年10月和2004年9月被列入日經指數和道瓊斯可持續發展指數。2001年7月,趨勢科技正式進入中國市場,并在上海、北京、廣州、成都等地設立分公司。以“創新服務用戶需求”為宗旨,為國內各行業用戶提供高質量的...