util.go 6.7 KB

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