util.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package gopay
  2. import (
  3. "crypto/tls"
  4. "encoding/json"
  5. "encoding/xml"
  6. "io"
  7. "math/rand"
  8. "reflect"
  9. "sort"
  10. "strconv"
  11. "strings"
  12. "time"
  13. "github.com/parnurzeal/gorequest"
  14. )
  15. type BodyMap map[string]interface{}
  16. // 设置参数
  17. func (bm BodyMap) Set(key string, value interface{}) {
  18. bm[key] = value
  19. }
  20. // 获取参数
  21. func (bm BodyMap) Get(key string) string {
  22. if bm == nil {
  23. return null
  24. }
  25. var (
  26. value interface{}
  27. ok bool
  28. v string
  29. )
  30. if value, ok = bm[key]; !ok {
  31. return null
  32. }
  33. if v, ok = value.(string); ok {
  34. return v
  35. }
  36. return convertToString(value)
  37. }
  38. func convertToString(v interface{}) (str string) {
  39. if v == nil {
  40. return null
  41. }
  42. var (
  43. bs []byte
  44. err error
  45. )
  46. if bs, err = json.Marshal(v); err != nil {
  47. return null
  48. }
  49. str = string(bs)
  50. return
  51. }
  52. // 删除参数
  53. func (bm BodyMap) Remove(key string) {
  54. delete(bm, key)
  55. }
  56. type xmlMapEntry struct {
  57. XMLName xml.Name
  58. Value string `xml:",chardata"`
  59. }
  60. func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
  61. if len(bm) == 0 {
  62. return nil
  63. }
  64. var (
  65. value string
  66. vKind reflect.Kind
  67. )
  68. if err = e.EncodeToken(start); err != nil {
  69. return
  70. }
  71. for k, v := range bm {
  72. vKind = reflect.ValueOf(v).Kind()
  73. switch vKind {
  74. case reflect.String:
  75. value = v.(string)
  76. case reflect.Int:
  77. value = Int2String(v.(int))
  78. case reflect.Int64:
  79. value = Int642String(v.(int64))
  80. case reflect.Float32:
  81. value = Float32ToString(v.(float32))
  82. case reflect.Float64:
  83. value = Float64ToString(v.(float64))
  84. default:
  85. value = ""
  86. }
  87. e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: value})
  88. }
  89. return e.EncodeToken(start.End())
  90. }
  91. func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
  92. for {
  93. var e xmlMapEntry
  94. err = d.Decode(&e)
  95. if err == io.EOF {
  96. break
  97. } else if err != nil {
  98. return
  99. }
  100. bm.Set(e.XMLName.Local, e.Value)
  101. }
  102. return
  103. }
  104. // ("bar=baz&foo=quux") sorted by key.
  105. func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
  106. var (
  107. buf strings.Builder
  108. keyList []string
  109. )
  110. for k := range bm {
  111. keyList = append(keyList, k)
  112. }
  113. sort.Strings(keyList)
  114. for _, k := range keyList {
  115. if v := bm.Get(k); v != null {
  116. buf.WriteString(k)
  117. buf.WriteByte('=')
  118. buf.WriteString(v)
  119. buf.WriteByte('&')
  120. }
  121. }
  122. buf.WriteString("key")
  123. buf.WriteByte('=')
  124. buf.WriteString(apiKey)
  125. return buf.String()
  126. }
  127. // ("bar=baz&foo=quux") sorted by key.
  128. func (bm BodyMap) EncodeAliPaySignParams() string {
  129. var (
  130. buf strings.Builder
  131. keyList []string
  132. )
  133. keyList = make([]string, 0, len(bm))
  134. for k := range bm {
  135. keyList = append(keyList, k)
  136. }
  137. sort.Strings(keyList)
  138. for _, k := range keyList {
  139. if v := bm.Get(k); v != null {
  140. buf.WriteString(k)
  141. buf.WriteByte('=')
  142. buf.WriteString(v)
  143. buf.WriteByte('&')
  144. }
  145. }
  146. return buf.String()[:buf.Len()-1]
  147. }
  148. // HttpAgent
  149. func HttpAgent() (agent *gorequest.SuperAgent) {
  150. return gorequest.New().TLSClientConfig(&tls.Config{InsecureSkipVerify: true})
  151. }
  152. // 获取随机字符串
  153. // length:字符串长度
  154. func GetRandomString(length int) string {
  155. str := "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
  156. var (
  157. result []byte
  158. b []byte
  159. r *rand.Rand
  160. )
  161. b = []byte(str)
  162. r = rand.New(rand.NewSource(time.Now().UnixNano()))
  163. for i := 0; i < length; i++ {
  164. result = append(result, b[r.Intn(len(b))])
  165. }
  166. return string(result)
  167. }
  168. // 解析时间
  169. func ParseDateTime(timeStr string) (datetime time.Time) {
  170. datetime, _ = time.ParseInLocation(TimeLayout, timeStr, time.Local)
  171. return
  172. }
  173. // 字符串转Float64
  174. func String2Float64(floatStr string) (floatNum float64) {
  175. floatNum, _ = strconv.ParseFloat(floatStr, 64)
  176. return
  177. }
  178. // 字符串转Float32
  179. func String2Float32(floatStr string) (floatNum float32) {
  180. float, _ := strconv.ParseFloat(floatStr, 32)
  181. floatNum = float32(float)
  182. return
  183. }
  184. // Float64转字符串
  185. // floatNum:float64数字
  186. // prec:精度位数(不传则默认float数字精度)
  187. func Float64ToString(floatNum float64, prec ...int) (floatStr string) {
  188. if len(prec) > 0 {
  189. floatStr = strconv.FormatFloat(floatNum, 'f', prec[0], 64)
  190. return
  191. }
  192. floatStr = strconv.FormatFloat(floatNum, 'f', -1, 64)
  193. return
  194. }
  195. // Float32转字符串
  196. // floatNum:float32数字
  197. // prec:精度位数(不传则默认float数字精度)
  198. func Float32ToString(floatNum float32, prec ...int) (floatStr string) {
  199. if len(prec) > 0 {
  200. floatStr = strconv.FormatFloat(float64(floatNum), 'f', prec[0], 32)
  201. return
  202. }
  203. floatStr = strconv.FormatFloat(float64(floatNum), 'f', -1, 32)
  204. return
  205. }
  206. // 字符串转Int
  207. func String2Int(intStr string) (intNum int) {
  208. intNum, _ = strconv.Atoi(intStr)
  209. return
  210. }
  211. // 字符串转Int32
  212. func String2Int32(intStr string) (int32Num int32) {
  213. intNum, _ := strconv.Atoi(intStr)
  214. int32Num = int32(intNum)
  215. return
  216. }
  217. // 字符串转Int64
  218. func String2Int64(intStr string) (int64Num int64) {
  219. intNum, _ := strconv.Atoi(intStr)
  220. int64Num = int64(intNum)
  221. return
  222. }
  223. // Int转字符串
  224. func Int2String(intNum int) (intStr string) {
  225. intStr = strconv.Itoa(intNum)
  226. return
  227. }
  228. // Int32转字符串
  229. func Int322String(intNum int32) (int32Str string) {
  230. // 10, 代表10进制
  231. int32Str = strconv.FormatInt(int64(intNum), 10)
  232. return
  233. }
  234. // Int64转字符串
  235. func Int642String(intNum int64) (int64Str string) {
  236. // 10, 代表10进制
  237. int64Str = strconv.FormatInt(intNum, 10)
  238. return
  239. }
  240. // 解密填充模式(去除补全码) PKCS7UnPadding
  241. // 解密时,需要在最后面去掉加密时添加的填充byte
  242. func PKCS7UnPadding(origData []byte) (bs []byte) {
  243. length := len(origData)
  244. unPaddingNumber := int(origData[length-1]) // 找到Byte数组最后的填充byte 数字
  245. if unPaddingNumber <= 16 {
  246. bs = origData[:(length - unPaddingNumber)] // 只截取返回有效数字内的byte数组
  247. } else {
  248. bs = origData
  249. }
  250. return
  251. }
  252. // 解密填充模式(去除补全码) PKCS5UnPadding
  253. // 解密时,需要在最后面去掉加密时添加的填充byte
  254. func PKCS5UnPadding(origData []byte) (bs []byte) {
  255. length := len(origData)
  256. unPaddingNumber := int(origData[length-1]) // 找到Byte数组最后的填充byte
  257. if unPaddingNumber <= 16 {
  258. bs = origData[:(length - unPaddingNumber)] // 只截取返回有效数字内的byte数组
  259. } else {
  260. bs = origData
  261. }
  262. return
  263. }