學習並了解到Html編碼的知識,源於工作中的產品需求。如果一個URL里面包含Puny Code(不僅僅指中文,還可能是韓文等Unicode里非英文的國家文字,本文以含中文的URL為例),而且這個URL剛好被保存在Html中作為鏈接,那么其中的Puny Code將會被編碼,因為中文等字符不能直接儲存在Html的鏈接中。如果這時使用工具提取Html中URL,所得到的URL就需要解碼處理。
一. Html編碼與解碼舉例
真實的URL:www.繁體中文.google.com
Html中的URL:
<a href="http://www.繁体中文.google.com">www.<span style='font-family:"MS Gothic"'>$BHKBNCfJ8(J</span>.google.com</a>
從<a>標簽的href中,可以看到,這時URL已經按照Html的格式被編碼,編碼后的URL是http://www.繁体中文.google.com
由此可見,Html對於Puny Code的編碼方式如下,以"繁"字舉例,
繁 —> 繁
主要格式是 "&#" + 一個十進制數 + ";",而這個十進制數正是漢字"繁"的中文內碼。"32321"轉換為十六進制是"7E41",通過查Unicode表可知,"7E41"正對應着漢字"繁",如下圖(Unicode Table:http://www.khngai.com/chinese/charmap/tbluni.php?page=3),
二. URL解碼實例(C++實現)
1. 算法思路
依次遍歷URL(假設URL保存在wchar_t寬字符數組中,使用wchar_t寬字符存儲Unicode編碼集),遇到特定格式&#,取出其中的數字32321,然后將其強制轉換成wchar_t寬字符,再將'繁'替換為此寬字符,這樣即可。
遍歷一遍URL后,便可以得到解碼后的URL。
2. 代碼
這里給出的只是字符轉換部分,如下,
1 //...從URL中取出編碼后的數字 2 wchar_t* strURL = L"323211"; 3 4 int iEncodeNum = _wtoi(strURL); 5 cout << "iEncodeNum = " << iEncodeNum << endl; 6 7 if((iEncodeNum & 0xFFFF0000) == 0) 8 { 9 wchar_t wDecodeNum = static_cast<wchar_t>(iEncodeNum); 10 //為輸出中文,設置wcout語言環境為中文 11 std::wcout.imbue(locale("chs")); 12 wcout << L"wDecodeNum = " << wDecodeNum << endl; 13 } 14 else 15 { 16 cout << "number > 65535, will cause truncation problem, can't handle this" << endl; 17 } 18 //將wDcodeNum替換入URL中,代替原來的繁 19 //...
這里注意的是,如果數字大於65535,即大於兩個字節,那么采用static_cast<wchar_t>做類型轉換,將導致截斷問題,解碼失敗。但一般來說常用的Unicode字符都在前65535個中,所以這個問題應該不用過多考慮。
運行結果:

三. 知識擴展:關於Unicode和UTF-8,UTF-16(因為之前我一直沒有搞清楚,在解這個問題的時候順便學習下,希望對大家也有幫助:-))
1. 字符集和字符編碼
字符集(Charset):是一個系統支持的所有抽象字符的集合。字符是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。
字符編碼(Character encoding)把字符集中的字符編碼為指定集合中某一對象,以便文本在計算機中存儲和通過通信網絡的傳遞。
2. Unicode和UTF-8,UTF-16
[Unicode]為表達任意語言的任意字符而設計。它使用4字節的數字來表達每個字母、符號,或者表意文字(ideograph)。每個數字代表唯一的至少在某種語言中使用的符號。Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三種字符編碼方案。需要注意的是,Unicode 只是一個符號集,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。
[UTF-16]盡管有Unicode字符非常多,但是實際上大多數人不會用到超過前65535個以外的字符。因此,就有了另外一種Unicode編碼方式,叫做UTF-16(因為16位 = 2字節)。UTF-16將0–65535范圍內的字符編碼成2個字節。
[UTF-8]一種針對Unicode的可變長度字符編碼,UTF-8使用一至四個字節為每個字符編碼。(字符的大小不確定,1到4個字節都有可能)。
字符的問題自己以前總是含混不清,經過這次學習相信有了更深了解,以后還要多多寫博客,至少一周一篇,總結工作學習中遇到的小問題,知識點:-)
Best Regards
Kevin Song
