在使用c#調用百度地圖Web服務api遇到的簽名(sn校驗)問題,在此記錄一下,(ip白名單校驗的請忽略)
1.首先獲取ak與sk,這個兩個東西可以從控制台中獲取到
2.在這個地址:sn簽名算法,里面提供了java,php,c#,python2.7的參考代碼
在百度提供的參考代碼中,其中c#的代碼中MD5加密方法是有問題的,(在筆者寫隨筆時,代碼還是有問題的,之后希望百度官方修復此問題)
把百度的MD5方法修改一下,簽名就正確了,api正常調用了,開心!!
這里是完整的簽名代碼

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Web; 6 7 namespace IpService.Code 8 { 9 public class BaiduAKSNCaculater 10 { 11 private static string MD5(string password) 12 { 13 try 14 { 15 System.Security.Cryptography.HashAlgorithm hash = System.Security.Cryptography.MD5.Create(); 16 byte[] hash_out = hash.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); 17 18 var md5_str=BitConverter.ToString(hash_out).Replace("-", ""); 19 return md5_str.ToLower(); 20 21 } 22 catch 23 { 24 25 throw; 26 } 27 } 28 29 private static string UrlEncode(string str) 30 { 31 str = System.Web.HttpUtility.UrlEncode(str); 32 byte[] buf = Encoding.ASCII.GetBytes(str);//等同於Encoding.ASCII.GetBytes(str) 33 for (int i = 0; i < buf.Length; i++) 34 if (buf[i] == '%') 35 { 36 if (buf[i + 1] >= 'a') buf[i + 1] -= 32; 37 if (buf[i + 2] >= 'a') buf[i + 2] -= 32; 38 i += 2; 39 } 40 return Encoding.ASCII.GetString(buf);//同上,等同於Encoding.ASCII.GetString(buf) 41 } 42 43 private static string HttpBuildQuery(IDictionary<string, string> querystring_arrays) 44 { 45 46 StringBuilder sb = new StringBuilder(); 47 foreach (var item in querystring_arrays) 48 { 49 sb.Append(UrlEncode(item.Key)); 50 sb.Append("="); 51 sb.Append(UrlEncode(item.Value)); 52 sb.Append("&"); 53 } 54 sb.Remove(sb.Length - 1, 1); 55 return sb.ToString(); 56 } 57 58 public static string CaculateAKSN(string ak, string sk, string url, IDictionary<string, string> querystring_arrays) 59 { 60 var queryString = HttpBuildQuery(querystring_arrays); 61 62 var str = UrlEncode(url + "?" + queryString + sk); 63 64 return MD5(str); 65 } 66 } 67 }
這里是調用代碼

1 public static string GetIPAreas() 2 { 3 var ip = "你要查詢的ip地址"; 4 var ak = "從百度控制台獲取到應用AK"; 5 var sk = "從百度控制台獲取到簽名SK"; 6 var uri = "http://api.map.baidu.com"; 7 var path = "/location/ip"; 8 var param = new Dictionary<string, string>(); 9 param.Add("ip", ip); 10 param.Add("ak", ak); 11 12 //注意:簽名的url參數,並非完整地址 13 var sn = BaiduAKSNCaculater.CaculateAKSN(ak, sk, path, param); 14 15 var url = string.Format("{0}{1}?ip={2}&ak={3}&sn={4}", 16 uri, 17 path, 18 ip, 19 ak, 20 sn); 21 22 var str = Code.HttpService.Get(url); 23 return str; 24 }
寫在最后,希望百度官方盡快修改示例中的代碼,這樣也方便別人拿來用