using System; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Collections; namespace SM2Crypto.Lib { class SignUtil { private static List ignoreSign = new List() { "signData", "encData", "extra" }; public static String getSignText(JObject jsonObject, String appSecret) { SortedDictionary signMap = new SortedDictionary(StringComparer.Ordinal); foreach (var entry in jsonObject) { if (!String.IsNullOrEmpty(entry.Value.ToString()) && !ignoreSign.Contains(entry.Key)) { signMap.Add(entry.Key, getValue(entry.Value)); } } List list = new List(); foreach (var entry in signMap) { if (!String.IsNullOrEmpty(getObjString(entry.Value))) { list.Add((String)entry.Key + "=" + (String)entry.Value + "&"); } } int size = list.Count(); String[] arrayToSort = (String[])list.ToArray(); Array.Sort(arrayToSort, new CaseInsensitiveComparer()); StringBuilder sb = new StringBuilder(); for (int i = 0; i < size; ++i) { sb.Append(arrayToSort[i]); } String signText = sb.Append("key=").Append(appSecret).ToString(); return signText; } public static String getObjString(Object obj) { return obj == null ? "" : (String)obj; } private static String getValue(Object value) { return value is String ? getObjString(value) : treeJsonParam(value); } private static String treeJsonParam(Object value) { String jsonParam = null; if (value is Dictionary) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); Dictionary nestedMap = (Dictionary)value; foreach (var entry in nestedMap) { treeNestedMap.Add(entry.Key.ToString(), entry.Value); } jsonParam = JsonConvert.SerializeObject(treeParams(treeNestedMap), Formatting.None); } else if (value is List) { List ar = (List)value; if (ar != null && ar.Count() != 0) jsonParam = JsonConvert.SerializeObject(treeList(ar), Formatting.None); } else if (value is JObject) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); JObject nestedMap = (JObject)value; foreach (var entry in nestedMap) { treeNestedMap.Add(entry.Key.ToString(), entry.Value); } jsonParam = JsonConvert.SerializeObject(treeParams(treeNestedMap), Formatting.None); } else if (value is JArray) { JArray ar = (JArray)value; if (ar != null && ar.Count() != 0) jsonParam = JsonConvert.SerializeObject(treeJsonArray(ar), Formatting.None); } else if (value is JValue) { JValue jval = (JValue)value; if (jval != null && !String.IsNullOrEmpty(jval.ToString())) { if (jval.ToString().ToLower().Trim().Equals("true") || jval.ToString().ToLower().Trim().Equals("false")) jsonParam = jval.ToString().ToLower().Trim(); else jsonParam = jval.Value.ToString(); } } else if (value is JProperty) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); JProperty nestedMap = (JProperty)value; treeNestedMap.Add(nestedMap.Name, nestedMap.Value); jsonParam = JsonConvert.SerializeObject(treeParams(treeNestedMap), Formatting.None); } else { jsonParam = value.ToString(); } return jsonParam; } private static SortedDictionary treeParams(SortedDictionary param) { if (param == null) { return new SortedDictionary(StringComparer.Ordinal); } else { SortedDictionary treeParam = new SortedDictionary(StringComparer.Ordinal); while (true) { foreach (var entry in param) { String key = (String)entry.Key; Object value = entry.Value; if (value is Dictionary) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); Dictionary nestedMap = (Dictionary)value; foreach (var nestedEntry in nestedMap) { treeNestedMap.Add(nestedEntry.Key.ToString(), nestedEntry.Value); } treeParam.Add(key, treeParams(treeNestedMap)); } else if (value is List) { List ar = (List)value; if (ar != null && ar.Count() != 0) treeParam.Add(key, treeList(ar)); } else if (value is JArray) { JArray ar = (JArray)value; if (ar != null && ar.Count() != 0) treeParam.Add(key, treeJsonArray(ar)); } else if (value is JObject) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); JObject nestedMap = (JObject)value; foreach (var nestedEntry in nestedMap) { treeNestedMap.Add(nestedEntry.Key.ToString(), nestedEntry.Value); } treeParam.Add(key, treeParams(treeNestedMap)); } else if (value is JValue) { JValue jval = (JValue)value; if (jval != null && !String.IsNullOrEmpty(jval.ToString())) { if (jval.ToString().ToLower().Trim().Equals("true") || jval.ToString().ToLower().Trim().Equals("false")) treeParam.Add(key, jval.ToString().ToLower().Trim()); else treeParam.Add(key, jval.ToString()); } } else if (value is JProperty) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); JProperty nestedMap = (JProperty)value; treeNestedMap.Add(nestedMap.Name, nestedMap.Value); treeParam.Add(key, treeParams(treeNestedMap)); } else if (!"".Equals(value) && value != null) { treeParam.Add(key, value.ToString()); } } return treeParam; } } } private static List treeList(List list) { if (list != null && list.Count() != 0) { JArray jsonArray = new JArray(); int size = list.Count(); for (int i = 0; i < size; ++i) { jsonArray.Add(list[i]); } return treeJsonArray(jsonArray); } else { return null; } } private static List treeJsonArray(JArray jarr) { if (jarr != null && jarr.Count() != 0) { List jsonArray = new List(); int size = jarr.Count(); for (int i = 0; i < size; ++i) { Object value = jarr[i]; if (value is List) { List ar = (List)value; if (ar != null && ar.Count() != 0) jsonArray.Add(treeList(ar)); } else if (value is JArray) { JArray ar = (JArray)value; if (ar != null && ar.Count() != 0) jsonArray.Add(treeJsonArray(ar)); } else if (value is JObject) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); JObject nestedMap = (JObject)value; foreach (var nestedEntry in nestedMap) { treeNestedMap.Add(nestedEntry.Key.ToString(), nestedEntry.Value); } jsonArray.Add(treeParams(treeNestedMap)); } else if (value is JValue) { JValue jval = (JValue)value; if (jval != null && !String.IsNullOrEmpty(jval.ToString())) { if (jval.ToString().ToLower().Trim().Equals("true") || jval.ToString().ToLower().Trim().Equals("false")) jsonArray.Add(jval.ToString().ToLower().Trim()); else jsonArray.Add(jval.ToString()); } } else if (value is JProperty) { SortedDictionary treeNestedMap = new SortedDictionary(StringComparer.Ordinal); JProperty nestedMap = (JProperty)value; treeNestedMap.Add(nestedMap.Name, nestedMap.Value); jsonArray.Add(treeParams(treeNestedMap)); } else if (!"".Equals(value)) { jsonArray.Add(value.ToString()); } } return jsonArray; } else { return null; } } } }