main.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package main
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "sort"
  10. "strings"
  11. )
  12. const (
  13. appKey = "DD3BZ-4643M-RJ76E-6WGEY-JZ4KO-2OBIG"
  14. appSK = "Px6Ig8s6ar0vFdnJXgcYoFvy4w3Z8wfr"
  15. apiURL = "https://apis.map.qq.com/ws/distance/v1/matrix"
  16. )
  17. // 请求参数结构体
  18. type RequestParams struct {
  19. Key string `json:"key"`
  20. From string `json:"from"`
  21. To string `json:"to"`
  22. Mode string `json:"mode"`
  23. }
  24. func main() {
  25. // 1. 原始参数
  26. params := RequestParams{
  27. Key: appKey,
  28. From: "39.940552,116.344101", // 北京展览馆
  29. To: "39.916585,116.319596", // 中塔公园
  30. Mode: "driving",
  31. }
  32. // 2. 取得结构体字段的排序后 kv 列表
  33. kv, err := toSortedKV(params)
  34. if err != nil {
  35. panic(err)
  36. }
  37. // 3. 拼成 querystring(不含 sig),再追加 SK
  38. tosign := "/ws/distance/v1/matrix?" + kv + appSK
  39. fmt.Println("request query:", tosign)
  40. // 4. 计算 MD5(小写)
  41. sig := fmt.Sprintf("%x", md5.Sum([]byte(tosign)))
  42. // 5. 组装最终 URL
  43. finalURL := apiURL + "?sig=" + sig
  44. fmt.Println("request url:", finalURL)
  45. // 6. 发送 GET 请求
  46. // 4. 发送 POST JSON
  47. jsonBytes, _ := json.Marshal(params)
  48. resp, err := http.Post(finalURL, "application/json", bytes.NewReader(jsonBytes))
  49. defer resp.Body.Close()
  50. body, _ := io.ReadAll(resp.Body)
  51. fmt.Printf("status=%d\nbody=%s\n", resp.StatusCode, body)
  52. }
  53. // 按字段名升序拼成 key=value
  54. func toSortedKV(v interface{}) (string, error) {
  55. // 结构体转 map
  56. var m map[string]interface{}
  57. b, _ := json.Marshal(v)
  58. if err := json.Unmarshal(b, &m); err != nil {
  59. return "", err
  60. }
  61. keys := make([]string, 0, len(m))
  62. for k := range m {
  63. keys = append(keys, k)
  64. }
  65. sort.Strings(keys)
  66. var sb strings.Builder
  67. for i, k := range keys {
  68. // 值 → 最短 JSON → 去首尾双引号
  69. valBytes, _ := json.Marshal(m[k])
  70. valStr := string(valBytes)
  71. if len(valStr) >= 2 && valStr[0] == '"' && valStr[len(valStr)-1] == '"' {
  72. valStr = valStr[1 : len(valStr)-1]
  73. }
  74. if i > 0 {
  75. sb.WriteByte('&')
  76. }
  77. sb.WriteString(k)
  78. sb.WriteByte('=')
  79. sb.WriteString(valStr)
  80. }
  81. return sb.String(), nil
  82. }