C# 參數簽名字符串按 ASCII碼排序,注意其中的坑


參數簽名中通常是按鍵值對中鍵名稱的ASCII按從小到大的順序排序后進行hash為簽名字符串。不要直接使用 SortedDictionary<string, string> 有坑的,他是按數字、小寫字母、大寫字母的順序排的,實際規則應該是數字、大寫字母、小寫字母的順序來排才對。一直使用他在支付寶和微信的接口中都沒問題,因為支付寶和微信的單詞是用下划線分隔的,今天接入的一家支付公司用的駝峰命名法坑就出現了。正確的打開姿勢如下:

/// <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),然后再對數值進行比較。

Array.Sort(vv, string.CompareOrdinal); //ASCII排序

注:掉入這個坑是因為起初不知道如何對字符做ASCII碼排序,於是百度了一把。得到的結果就是這個 C# 參數按照ASCII碼從小到大排序(字典序)  而當我采用這種方式時,銀行驗簽那步始終通不過,調試發現我排序后的結果和銀行那邊的不同。這篇博文的博主可能自己也沒發現這個坑吧。

整理來源:

http://www.cnblogs.com/similar/p/6739293.html

http://www.cnblogs.com/similar/p/6739293.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM