在沒有 uncode 的時代, 用 256 個 acsii 只是方便了英文, 其他文字怎麼辦?
那時是各自為政的, 譬如中文就有: gb2312-80(國內簡體)、big5(台灣繁體)、hkscs(香港繁體), 但它們互不相容.
gb2312(2023年) 後來公升級到 gbk(2023年), 現在電腦上使用的是 gb18030(2023年), 這個系列是向後相容的.
區位碼的概念是在 gb2312 時提出的, gb2312 是乙個 94*94 的二維表, 行就是 "區"、列就是 "位", 譬如 "萬" 字在 45 區 82 位, 所以 "萬" 字的區位碼是: 4582.
00-09 區(682個): 是符號、數字、英文本元...製表符等;
10-15 區: 空白, 留待擴充套件;
16-55 區(3755個): 常用漢字(也有叫一級漢字), 按拼音排序;
56-87 區(3008個): 非常用漢字(也有叫二級漢字), 這是按部首排序的;
88-94 區: 空白, 留待擴充套件.
還有兩個概念: 國際碼、內碼.
先轉一下話題: 開啟記事本輸入 "萬" 字, 儲存(編碼選擇 ansi); 然後用二進位制編輯器(譬如: ultraedit) 開啟, 會看到:
cd f2, 這就是 "萬" 字的內碼!
那什麼又是國際碼呢?
咱們的 gb2312 用乙個二維表表示了咱們需要的字元, 其他文字可能也是如此; 為了區別, 所以有國際組織規定把咱們的 "區" 和 "位" 分別加上 32(十六進製制表示: $20; 二進位制表示: 00100000) 作為國際碼(那其他文字應該加另外乙個不同的數字).
這樣我們可以算出(45+32, 82+32):
"萬" 字的國際碼是 77 114($4d72)
不過這還不能在計算機上使用, 因為這樣會和早已通用的 ascii 碼混淆(導致亂碼), 譬如: 77 是 ascii 的 "m", 114 是 ascii 的 "r".
所以又有規定把每個位元組的最高位都從 0 換成 1(這之前它們都是 0), 或者說把每個位元組(區和位)都再加上 128(十六進製制的: $80; 二進位制的: 10000000), 從而得到 "機內碼", 也就是前面所說的 "內碼".
總結一下: 從區位碼, 區和位分別 +32 得到國際碼, 再分別 +128 得到內碼;
簡化一下: 區位碼的區和位分別 +160 即可得到內碼, 用十六進製制表示: 區位碼 + $a0a0 = 內碼.
驗證一下前面從記事本輸入得到的 cd f2:
45 + 160 = 205; (205 就是 十六進製制的 $cd)
82 + 160 = 242; (242 就是 十六進製制的 $f2)
這樣, 內碼的兩個位元組的最高位就都是 1 了, 另外 ascii 的(0-254)最高位都是 0, 所以有人也使用這個特點來區別漢字.
雖然 window 2000 開始, 系統已經使用 uncode 編碼了, 其實咱們現在還是使用的這種雙位元組內碼, 這是系統根據我們選擇的字符集自動轉換的.
Delphi中處理漢字的方法
在delphi中乙個漢字佔兩個位元組,各種字串處理函式,直接處理字串中漢字時經常會發生亂碼或不顯示。我在處理時也是弄了半天,到處找資料,一下是找到的幾種處理方法。在delphi7下測試通過。一.中文所用的字元全是雙位元組字元,英文所用的位元組全是單位元組字元,也就是mbsinglebyte。本例項是...
delphi學習筆記 TADOQuery
delphi 資料庫查詢 tadoquery 在乙個程式中你會多次查詢資料庫的,因此在你寫的查詢方法中定義乙個區域性的adoquery就可以了,它返回乙個資料集 recordset。最簡單的應用如下 function getdata recordset 獲取一張表中的全部資料 recordset是一...
學習筆記(九)
字元處理只針對c n d t string型別,不做型別轉換,都按照c型別處理,也可以處理這些型別構成的結構體,有專門的字串比較 定位操作 concatenate first name last name into first name separated by separate.write fir...