參數簽名中一般是按鍵值對中鍵名稱的ASCII按從小到大的順序排序後進行hash爲簽名字符串。不要直接使用 SortedDictionary<string, string> 有坑的,他是按數字、小寫字母、大寫字母的順序排的,實際規則應該是數字、大寫字母、小寫字母的順序來排纔對。一直使用他在支付寶和微信的接口中都沒問題,由於支付寶和微信的單詞是用下劃線分隔的,今天接入的一家支付公司用的駝峯命名法坑就出現了。正確的打開姿式以下:html
/// <summary> /// ASCII值排序 /// </summary> public class OrdinalComparer : System.Collections.Generic.IComparer<String> { public int Compare(String x, String y) { return string.CompareOrdinal(x, y); } } //使用 //SortedDictionary<string, string> sDic 待排序的鍵值對 var sArr = sDic.OrderBy(x => x.Key, new OrdinalComparer()).ToDictionary(x => x.Key, y => y.Value); //而後 foreach sArr 就OK了 //或者轉爲數組再排序 string[] arr = new string[sDic.Count]; Array.Sort(arr, string.CompareOrdinal); //ASCII排序
在和銀行作數據對接時,涉及到數據傳輸時的驗籤及加密。其中數據簽名方案中就要求數據項根據屬性名按 ASCII碼 進行升序排序。C#中的ASCII碼排序並非表面上那麼簡單,一不當心就入坑了。由於C#的排序默認並非按照ASCII碼進行排序的。舉個例子, 我有這樣一個字符串數組,而後對其排序。數組
string[] vv = { "1", "2", "A", "a", "B", "b" }; Array.Sort(vv); //結果 1 2 a A b B
若是是按照ASCII碼進行排序的話,順序應該是: 1, 2, A, B, a, b 而實際排序後的結果則是:1, 2, a, A, b, B . 這也就是說Sort()方法默認狀況下並非按ASCII碼進行排序的。以後我也一樣測試了C#中的OrderBy()的排序,發現它默認狀況下也並非按照ASCII碼進行的排序。微信
string[] vv = { "1", "2", "A", "a", "B", "b" }; vv.OrderBy(x => x); //結果 1 2 a A b B
那麼既然默認排序不是按ASCII碼進行的排序,咱們要怎麼作呢? 看下面代碼,只須要在原來排序方法上再加個參數: string.CompareOrdinal。string.CompareOrdinal會把每一個字符先轉成相應的數值(如 a 轉爲數值 97),而後再對數值進行比較。post
Array.Sort(vv, string.CompareOrdinal); //ASCII排序
注:掉入這個坑是由於起初不知道如何對字符作ASCII碼排序,因而百度了一把。獲得的結果就是這個 C# 參數按照ASCII碼從小到大排序(字典序) 而當我採用這種方式時,銀行驗籤那步始終通不過,調試發現我排序後的結果和銀行那邊的不一樣。這篇博文的博主可能本身也沒發現這個坑吧。測試
整理來源:加密
http://www.cnblogs.com/similar/p/6739293.htmlurl
http://www.cnblogs.com/similar/p/6739293.htmlspa