最近在處理一段特殊的程式邏輯,原本以為兩個相同字串經過 UrlEncode(),再透過某個加密演算法
(如:DES或AES )後,內容應該會是一樣,畢竟是相同字串,但透過比對後,發現竟然不是這樣,
這其中貓膩究竟是甚麼呢...
先來說說原始的字串,是一個 json 內文,類似像這樣
{"name":"Test","age":1}
另外這段文字,分別使用 JavaScript 與C# 內建的函式對這段文字 UrlEncode,以下是編碼後的狀況
JavaScript:encodeURI(json)
結果:"%7B%22name%22:%22Test%22,%22age%22:1%7D"
C#:HttpUtility.UrlEncode(json)
結果:"%7b%22name%22%3a%22Test%22%2c%22age%22%3a1%7d"
以上兩者的UrlEncode 很明顯從外觀可以看出差異,其中
「{」
JS:%7B
C#:%7b
「:」
JS:保留不動
C#:3a
「,」
JS:保留不動
C#:2c
「}」
JS:%7D
C#:%7d
雖然兩者Encode 後產出的字串,表面上有所差異,但若經過C# HttpUtility.UrlDecode()
都是可以解碼回原本的字串,如下操作
所以,其實若沒有將UrlEncode 後的結果做後續應用,應該不會有甚麼大問題;假設,現需要
將兩者編碼後的結果做其中一種可逆加密計算如 AES
「%7B%22name%22:%22Test%22,%22age%22:1%7D」 加密:
結果:a+CTFrJtU1/oG3nCBJ0NX5WVLcb9eexRvjE80sa9DdNLJg4B8RM8x/OTmbgnNMX2
「%7b%22name%22%3a%22Test%22%2c%22age%22%3a1%7d」 加密:
結果:Fc9zPyete4mb1u1AkUtl4CcHozJ+2GCuh1WAqdqPzKJBYziEhwxRCBNznpB4dZM6
由以上結果很明顯可看出差異
回到最初的問題,為何都是 UrlEncode 兩者產出的值會不同?參考微軟,說明
space (空白)會被轉換成 +,而< and > 會被轉換成 %3c and %3e
但是「{」「}」與「,」並沒有交代,難保其他沒有被列舉的符號其實也是會被置換,真是傷腦筋,
文章下方有說明,建議使用 WebUtility 類別
WebUtility 類別是在 System.Net Namespace 底下,以下直接使用
結果
由以上可以發現,其 UrlEncode 產出的值與 JavsScript 產出的結果一致
但有點美中不足的是 WebUtility.UrlEncode() 函式僅在 .net framework 4.5 以上才支援,可惜 ~
所幸,天公疼惜,找到黑大這篇,這邊黑哥是遇到UrlEncode 後空白變+號的狀況,
其中,文末有提到可使用 「Uri.EscapeDataString() 」
而Decode 可以使用「Uri.UnescapeDataString(value)」
完美結案..
參考
沒有留言:
張貼留言