You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.0 KiB

3 years ago
  1. package utils
  2. import (
  3. "bytes"
  4. "crypto/hmac"
  5. "crypto/md5"
  6. "crypto/sha256"
  7. "encoding/hex"
  8. "encoding/json"
  9. "encoding/xml"
  10. "fmt"
  11. "sort"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. // Struct2Map 结构体转map
  17. func Struct2Map(params interface{}) (m map[string]interface{}) {
  18. m = make(map[string]interface{})
  19. if b, err := json.Marshal(params); err == nil {
  20. _ = json.Unmarshal(b, &m)
  21. }
  22. return
  23. }
  24. // SortKey map排序
  25. func SortKey(m map[string]interface{}) string {
  26. arr := make([]string, 0)
  27. for k := range m {
  28. arr = append(arr, k)
  29. }
  30. strArr := make([]string, 0)
  31. for _, key := range arr {
  32. switch m[key].(type) {
  33. case string:
  34. value := m[key].(string)
  35. if value != "" {
  36. strArr = append(strArr, key+"="+value)
  37. }
  38. case int:
  39. if m[key] != 0 {
  40. value := strconv.Itoa(m[key].(int))
  41. strArr = append(strArr, key+"="+value)
  42. }
  43. case float64:
  44. if m[key] != 0.00 {
  45. value := strconv.Itoa(int(m[key].(float64)))
  46. strArr = append(strArr, key+"="+value)
  47. }
  48. }
  49. }
  50. sort.Strings(strArr)
  51. return strings.Join(strArr, "&")
  52. }
  53. // MAP2XML map转xml
  54. func MAP2XML(m map[string]interface{}) string {
  55. str := ""
  56. for k, v := range m {
  57. switch v.(type) {
  58. case string:
  59. str = str + fmt.Sprintf("<%s><![CDATA[%s]]></%s>", k, v, k)
  60. case int:
  61. str = str + fmt.Sprintf("<%s><![CDATA[%d]]></%s>", k, v, k)
  62. case interface{}:
  63. b, _ := json.Marshal(v)
  64. str = str + fmt.Sprintf("<%s><![CDATA[%s]]></%s>", k, string(b), k)
  65. }
  66. }
  67. return "<xml>" + str + "</xml>"
  68. }
  69. // MAPMerge map合并
  70. func MAPMerge(args ...map[string]interface{}) (m map[string]interface{}) {
  71. m = make(map[string]interface{})
  72. for _, item := range args {
  73. for k, v := range item {
  74. m[k] = v
  75. }
  76. }
  77. return m
  78. }
  79. // XML2MAP xml转map
  80. func XML2MAP(b []byte) (m map[string]string) {
  81. decoder := xml.NewDecoder(bytes.NewReader(b))
  82. m = make(map[string]string)
  83. tag := ""
  84. for {
  85. token, err := decoder.Token()
  86. if err != nil {
  87. break
  88. }
  89. switch t := token.(type) {
  90. case xml.StartElement:
  91. if t.Name.Local != "xml" {
  92. tag = t.Name.Local
  93. } else {
  94. tag = ""
  95. }
  96. break
  97. case xml.EndElement:
  98. break
  99. case xml.CharData:
  100. data := strings.TrimSpace(string(t))
  101. if len(data) != 0 {
  102. m[tag] = data
  103. }
  104. break
  105. }
  106. }
  107. return
  108. }
  109. // RandomStr 随机字符串
  110. func RandomStr() string {
  111. return strings.ToUpper(MD5(strconv.FormatInt(time.Now().UnixNano(), 19)))
  112. }
  113. // MD5 md5加密
  114. func MD5(str string) string {
  115. hash := md5.Sum([]byte(str))
  116. md5str := fmt.Sprintf("%x", hash)
  117. return strings.ToUpper(md5str)
  118. }
  119. // Sign 生成签名 HMAC-SHA256加密
  120. func SignHMACSHA256(m map[string]interface{}, key string) (sign string) {
  121. sign = HmacSha256(SortKey(m)+"&key="+key, key)
  122. return
  123. }
  124. // SignMD5 生成签名 MD5加密
  125. func SignMD5(m map[string]interface{}, key string) (sign string) {
  126. sign = MD5(SortKey(m) + "&key=" + key)
  127. return
  128. }
  129. // HmacSha256 HMAC-SHA256加密
  130. func HmacSha256(str string, key string) string {
  131. h := hmac.New(sha256.New, []byte(key))
  132. h.Write([]byte(str))
  133. return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
  134. }