common.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. package util
  2. import (
  3. "crypto/md5"
  4. cryptoRand "crypto/rand"
  5. "encoding/hex"
  6. "encoding/json"
  7. "encoding/xml"
  8. "fmt"
  9. bson "gopkg.in/mgo.v2/bson"
  10. "io"
  11. "log"
  12. "math"
  13. "math/big"
  14. mathRand "math/rand"
  15. "net/url"
  16. "reflect"
  17. "regexp"
  18. "runtime"
  19. "sort"
  20. "strconv"
  21. "strings"
  22. "time"
  23. "github.com/dchest/captcha"
  24. )
  25. const (
  26. tmp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900"
  27. )
  28. //短地址加密
  29. func EncodeArticleId(keys ...string) string {
  30. kstr := strings.Join(keys, ",")
  31. return SE.EncodeString(kstr)
  32. }
  33. //短地址解密
  34. func DecodeArticleId(id string) []string {
  35. return strings.Split(SE.DecodeString(id), ",")
  36. }
  37. //短地址加密,二次加密带校验和
  38. func EncodeArticleId2ByCheck(keys ...string) string {
  39. kstr := strings.Join(keys, ",")
  40. kstr = SE.EncodeStringByCheck(kstr)
  41. return url.QueryEscape("ABC" + SE2.EncodeStringByCheck(kstr))
  42. }
  43. //短地址解密,二次解密带校验和
  44. func DecodeArticleId2ByCheck(id string) []string {
  45. if !strings.Contains(id, "+") { //新加密算法解密
  46. id, _ = url.QueryUnescape(id)
  47. }
  48. if id[:3] == "ABC" { //前三位为ABC是新加密数据
  49. kstr := SE2.DecodeStringByCheck(id[3:])
  50. return strings.Split(SE.DecodeStringByCheck(kstr), ",")
  51. } else { //历史数据
  52. rep := DecodeArticleId(id)
  53. oldpushid := "58f87a9561a0721f157bc74d" //剑鱼1.9发版前最后一次推送信息id
  54. if rep[0] > oldpushid {
  55. return []string{""}
  56. } else {
  57. return rep
  58. }
  59. }
  60. }
  61. func Uuid(length int) string {
  62. ret := []string{}
  63. r := mathRand.New(mathRand.NewSource(time.Now().UnixNano()))
  64. for i := 0; i < length; i++ {
  65. index := r.Intn(62)
  66. ret = append(ret, tmp[index:index+1])
  67. }
  68. return strings.Join(ret, "")
  69. }
  70. //计算字符串和值
  71. func Sumstring(code string) (sum int) {
  72. tmp := []rune(code)
  73. for _, v := range tmp {
  74. sum = sum + int(v)
  75. }
  76. return
  77. }
  78. //获取随机数
  79. func GetRandom(n int) string {
  80. var idChars = []byte("0123456789")
  81. b := captcha.RandomDigits(n)
  82. for i, c := range b {
  83. b[i] = idChars[c]
  84. }
  85. return string(b)
  86. }
  87. //获取复杂的随机数
  88. func GetLetterRandom(length int, flag ...bool) string {
  89. var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
  90. var mod byte = 52
  91. if len(flag) > 0 && flag[0] {
  92. idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  93. mod = 26
  94. }
  95. b := make([]byte, length)
  96. maxrb := byte(256 - (256 % int(mod)))
  97. i := 0
  98. EXIT:
  99. for {
  100. r := make([]byte, length+(length/4))
  101. if _, err := io.ReadFull(cryptoRand.Reader, r); err != nil {
  102. panic("captcha: error reading random source: " + err.Error())
  103. }
  104. for _, c := range r {
  105. if c > maxrb {
  106. continue
  107. }
  108. b[i] = c % mod
  109. i++
  110. if i == length {
  111. break EXIT
  112. }
  113. }
  114. }
  115. for i, c := range b {
  116. b[i] = idChars[c]
  117. }
  118. return string(b)
  119. }
  120. /*获取复杂的随机数,数字和字母的组合
  121. * c > 2 数字的个数和字母的个数随机分配
  122. * n 数字的个数
  123. * l 字母的个数
  124. */
  125. func GetComplexRandom(c, n, l int) string {
  126. if c < 2 && (n < 1 || l < 1) {
  127. return "--"
  128. }
  129. r := mathRand.New(mathRand.NewSource(time.Now().UnixNano()))
  130. myCommonMethod := func(flag bool) int {
  131. if flag {
  132. return r.Intn(c-1) + 1
  133. } else {
  134. return r.Intn(c)
  135. }
  136. }
  137. if c >= 2 {
  138. n = myCommonMethod(true)
  139. l = c - n
  140. } else {
  141. c = l + n
  142. }
  143. value := GetRandom(n) + GetLetterRandom(l)
  144. var array = strings.Split(value, "")
  145. for i := 0; i < c/2; i++ {
  146. r1 := myCommonMethod(false)
  147. r2 := myCommonMethod(false)
  148. o := array[r1]
  149. array[r1] = array[r2]
  150. array[r2] = o
  151. }
  152. return strings.Join(array, "")
  153. }
  154. /*隐藏部分账号
  155. *返回手机号:150...70765 邮箱:...shenjun@vip.qq.com
  156. */
  157. func EncryCode(value string) string {
  158. if len(value) == 0 {
  159. return value
  160. } else if strings.Contains(value, "@") {
  161. start := strings.Index(value, "@") / 2
  162. if start == 0 {
  163. start++
  164. }
  165. value = "...." + string(value[start:])
  166. } else {
  167. value = string(value[0:3]) + "..." + string(value[len(value)-4:])
  168. }
  169. return value
  170. }
  171. //生成32位md5字串
  172. func GetMd5String(s string) string {
  173. h := md5.New()
  174. h.Write([]byte(s))
  175. return hex.EncodeToString(h.Sum(nil))
  176. }
  177. //obj(string,M)转M,查询用到
  178. func ObjToMap(obj interface{}) *map[string]interface{} {
  179. data := make(map[string]interface{})
  180. if s, ok := obj.(string); ok {
  181. json.Unmarshal([]byte(strings.Replace(s, "'", "\"", -1)), &data)
  182. } else if s1, ok1 := obj.(map[string]interface{}); ok1 {
  183. data = s1
  184. } else if s1, ok1 := obj.(*map[string]interface{}); ok1 {
  185. return s1
  186. } else {
  187. data = nil
  188. }
  189. return &data
  190. }
  191. /*UTC类型时间转字符串
  192. *flag==true,日期格式yyyy-mm-dd hh:mm:ss
  193. *flag==false,日期格式yyyy-mm-dd
  194. */
  195. func LongToDate(date interface{}, flag bool) string {
  196. var int64Date int64
  197. if l1, ok1 := date.(float64); ok1 {
  198. int64Date = int64(l1)
  199. } else if l2, ok2 := date.(int64); ok2 {
  200. int64Date = l2
  201. } else if l3, ok3 := date.(int); ok3 {
  202. int64Date = int64(l3)
  203. }
  204. t := time.Unix(int64Date, 0)
  205. if flag {
  206. return t.Format("2006-01-02 15:04:05")
  207. } else {
  208. return t.Format("2006-01-02")
  209. }
  210. }
  211. func IntAll(num interface{}) int {
  212. return IntAllDef(num, 0)
  213. }
  214. func Int64All(num interface{}) int64 {
  215. if i, ok := num.(int64); ok {
  216. return int64(i)
  217. } else if i0, ok0 := num.(int32); ok0 {
  218. return int64(i0)
  219. } else if i1, ok1 := num.(float64); ok1 {
  220. return int64(i1)
  221. } else if i2, ok2 := num.(int); ok2 {
  222. return int64(i2)
  223. } else if i3, ok3 := num.(float32); ok3 {
  224. return int64(i3)
  225. } else if i4, ok4 := num.(string); ok4 {
  226. i64, _ := strconv.ParseInt(i4, 10, 64)
  227. //in, _ := strconv.Atoi(i4)
  228. return i64
  229. } else if i5, ok5 := num.(int16); ok5 {
  230. return int64(i5)
  231. } else if i6, ok6 := num.(int8); ok6 {
  232. return int64(i6)
  233. } else if i7, ok7 := num.(*big.Int); ok7 {
  234. in, _ := strconv.ParseInt(fmt.Sprint(i7), 10, 64)
  235. return int64(in)
  236. } else if i8, ok8 := num.(*big.Float); ok8 {
  237. in, _ := strconv.ParseInt(fmt.Sprint(i8), 10, 64)
  238. return int64(in)
  239. } else {
  240. return 0
  241. }
  242. }
  243. func Float64All(num interface{}) float64 {
  244. if i, ok := num.(float64); ok {
  245. return float64(i)
  246. } else if i0, ok0 := num.(int32); ok0 {
  247. return float64(i0)
  248. } else if i1, ok1 := num.(int64); ok1 {
  249. return float64(i1)
  250. } else if i2, ok2 := num.(int); ok2 {
  251. return float64(i2)
  252. } else if i3, ok3 := num.(float32); ok3 {
  253. return float64(i3)
  254. } else if i4, ok4 := num.(string); ok4 {
  255. in, _ := strconv.ParseFloat(i4, 64)
  256. return in
  257. } else if i5, ok5 := num.(int16); ok5 {
  258. return float64(i5)
  259. } else if i6, ok6 := num.(int8); ok6 {
  260. return float64(i6)
  261. } else if i6, ok6 := num.(uint); ok6 {
  262. return float64(i6)
  263. } else if i6, ok6 := num.(uint8); ok6 {
  264. return float64(i6)
  265. } else if i6, ok6 := num.(uint16); ok6 {
  266. return float64(i6)
  267. } else if i6, ok6 := num.(uint32); ok6 {
  268. return float64(i6)
  269. } else if i6, ok6 := num.(uint64); ok6 {
  270. return float64(i6)
  271. } else if i7, ok7 := num.(*big.Float); ok7 {
  272. in, _ := strconv.ParseFloat(fmt.Sprint(i7), 64)
  273. return float64(in)
  274. } else if i8, ok8 := num.(*big.Int); ok8 {
  275. in, _ := strconv.ParseFloat(fmt.Sprint(i8), 64)
  276. return float64(in)
  277. } else {
  278. return 0
  279. }
  280. }
  281. func IntAllDef(num interface{}, defaultNum int) int {
  282. if i, ok := num.(int); ok {
  283. return int(i)
  284. } else if i0, ok0 := num.(int32); ok0 {
  285. return int(i0)
  286. } else if i1, ok1 := num.(float64); ok1 {
  287. return int(i1)
  288. } else if i2, ok2 := num.(int64); ok2 {
  289. return int(i2)
  290. } else if i3, ok3 := num.(float32); ok3 {
  291. return int(i3)
  292. } else if i4, ok4 := num.(string); ok4 {
  293. in, _ := strconv.Atoi(i4)
  294. return int(in)
  295. } else if i5, ok5 := num.(int16); ok5 {
  296. return int(i5)
  297. } else if i6, ok6 := num.(int8); ok6 {
  298. return int(i6)
  299. } else if i7, ok7 := num.(*big.Int); ok7 {
  300. in, _ := strconv.Atoi(fmt.Sprint(i7))
  301. return int(in)
  302. } else if i8, ok8 := num.(*big.Float); ok8 {
  303. in, _ := strconv.Atoi(fmt.Sprint(i8))
  304. return int(in)
  305. } else {
  306. return defaultNum
  307. }
  308. }
  309. func ObjToString(old interface{}) string {
  310. if nil == old {
  311. return ""
  312. } else {
  313. r, _ := old.(string)
  314. return r
  315. }
  316. }
  317. func ObjToStringDef(old interface{}, defaultstr string) string {
  318. if nil == old {
  319. return defaultstr
  320. } else {
  321. r, _ := old.(string)
  322. if r == "" {
  323. return defaultstr
  324. }
  325. return r
  326. }
  327. }
  328. //对象数组转成string数组
  329. func ObjArrToStringArr(old []interface{}) []string {
  330. if old != nil {
  331. new := make([]string, len(old))
  332. for i, v := range old {
  333. new[i] = v.(string)
  334. }
  335. return new
  336. } else {
  337. return nil
  338. }
  339. }
  340. //对象数组转成map数组
  341. func ObjArrToMapArr(old []interface{}) []map[string]interface{} {
  342. if old != nil {
  343. new := make([]map[string]interface{}, len(old))
  344. for i, v := range old {
  345. new[i] = v.(map[string]interface{})
  346. }
  347. return new
  348. } else {
  349. return nil
  350. }
  351. }
  352. //map数组转成对象数组
  353. func MapArrToObjArr(old []map[string]interface{}) []interface{} {
  354. if old != nil {
  355. new := make([]interface{}, len(old))
  356. for i, v := range old {
  357. new[i] = v
  358. }
  359. return new
  360. } else {
  361. return nil
  362. }
  363. }
  364. func SubstrByByte(str string, length int) string {
  365. bs := []byte(str)[:length]
  366. bl := 0
  367. for i := len(bs) - 1; i >= 0; i-- {
  368. switch {
  369. case bs[i] >= 0 && bs[i] <= 127:
  370. return string(bs[:i+1])
  371. case bs[i] >= 128 && bs[i] <= 191:
  372. bl++
  373. case bs[i] >= 192 && bs[i] <= 253:
  374. cl := 0
  375. switch {
  376. case bs[i]&252 == 252:
  377. cl = 6
  378. case bs[i]&248 == 248:
  379. cl = 5
  380. case bs[i]&240 == 240:
  381. cl = 4
  382. case bs[i]&224 == 224:
  383. cl = 3
  384. default:
  385. cl = 2
  386. }
  387. if bl+1 == cl {
  388. return string(bs[:i+cl])
  389. }
  390. return string(bs[:i])
  391. }
  392. }
  393. return ""
  394. }
  395. func SubString(str string, begin, length int) (substr string) {
  396. // 将字符串的转换成[]rune
  397. rs := []rune(str)
  398. lth := len(rs)
  399. // 简单的越界判断
  400. if begin < 0 {
  401. begin = 0
  402. }
  403. if begin >= lth {
  404. begin = lth
  405. }
  406. end := begin + length
  407. if end > lth {
  408. end = lth
  409. }
  410. // 返回子串
  411. return string(rs[begin:end])
  412. }
  413. //捕获异常
  414. func Try(fun func(), handler func(interface{})) {
  415. defer func() {
  416. if err := recover(); err != nil {
  417. for skip := 1; ; skip++ {
  418. _, file, line, ok := runtime.Caller(skip)
  419. if !ok {
  420. break
  421. }
  422. go log.Printf("%v,%v\n", file, line)
  423. }
  424. handler(err)
  425. }
  426. }()
  427. fun()
  428. }
  429. //3目运算
  430. func If(b bool, to, fo interface{}) interface{} {
  431. if b {
  432. return to
  433. } else {
  434. return fo
  435. }
  436. }
  437. //HashCode值
  438. func HashCode(uid string) int {
  439. var h uint32 = 0
  440. rs := []rune(uid)
  441. for i := 0; i < len(rs); i++ {
  442. h = 31*h + uint32(rs[i])
  443. }
  444. return int(h)
  445. }
  446. //获取离n天的秒差
  447. func GetDayStartSecond(n int) int64 {
  448. now := time.Now()
  449. tom := time.Date(now.Year(), now.Month(), now.Day()+n, 0, 0, 0, 0, time.Local)
  450. return tom.Unix()
  451. }
  452. func InterfaceArrTointArr(arr []interface{}) []int {
  453. tmp := make([]int, 0)
  454. for _, v := range arr {
  455. tmp = append(tmp, int(v.(float64)))
  456. }
  457. return tmp
  458. }
  459. func InterfaceArrToint64Arr(arr []interface{}) []int64 {
  460. tmp := make([]int64, 0)
  461. for _, v := range arr {
  462. tmp = append(tmp, int64(v.(float64)))
  463. }
  464. return tmp
  465. }
  466. //根据bsonID转string
  467. func BsonIdToSId(uid interface{}) string {
  468. if uid == nil {
  469. return ""
  470. } else if u, ok := uid.(string); ok {
  471. return u
  472. } else {
  473. return fmt.Sprintf("%x", string(uid.(bson.ObjectId)))
  474. }
  475. }
  476. func StringTOBsonId(id string) (bid bson.ObjectId) {
  477. defer Catch()
  478. if id != "" {
  479. bid = bson.ObjectIdHex(id)
  480. }
  481. return
  482. }
  483. func GetSubDay(t1 int64) int {
  484. tt1 := time.Unix(t1, 0)
  485. tt2 := time.Now()
  486. nt1 := time.Date(tt1.Year(), tt1.Month(), tt1.Day(), 0, 0, 0, 0, time.Local)
  487. nt2 := time.Date(tt2.Year(), tt2.Month(), tt2.Day(), 0, 0, 0, 0, time.Local)
  488. return int((nt1.Unix() - nt2.Unix()) / 86400)
  489. }
  490. func StartWith(value, str string) bool {
  491. ok, _ := regexp.MatchString("^"+str, value)
  492. return ok
  493. }
  494. func EndWith(value, str string) bool {
  495. ok, _ := regexp.MatchString(str+"$", value)
  496. return ok
  497. }
  498. //出错拦截
  499. func Catch() {
  500. if r := recover(); r != nil {
  501. log.Println(r)
  502. for skip := 0; ; skip++ {
  503. _, file, line, ok := runtime.Caller(skip)
  504. if !ok {
  505. break
  506. }
  507. go log.Printf("%v,%v\n", file, line)
  508. }
  509. }
  510. }
  511. func ConvertFileSize(s int) string {
  512. size := float64(s)
  513. var kb float64 = 1024
  514. var mb float64 = kb * 1024
  515. var gb float64 = mb * 1024
  516. if size >= gb {
  517. return fmt.Sprintf("%.1f GB", float64(size/gb))
  518. } else if size >= mb {
  519. f := float64(size / mb)
  520. if f > 100 {
  521. return fmt.Sprintf("%.0f MB", f)
  522. }
  523. return fmt.Sprintf("%.1f MB", f)
  524. } else if size >= kb {
  525. f := float64(size / kb)
  526. if f > 100 {
  527. return fmt.Sprintf("%.0f KB", f)
  528. }
  529. return fmt.Sprintf("%.1f KB", f)
  530. }
  531. return fmt.Sprintf("%d B", s)
  532. }
  533. //MD5签名
  534. func WxSign(format string, param ...interface{}) string {
  535. data := fmt.Sprintf(format, param...)
  536. h := md5.New()
  537. h.Write([]byte(data))
  538. sign := strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
  539. return sign
  540. }
  541. //计算时差
  542. func TimeDiff(date time.Time) string {
  543. var date1 = date //开始时间
  544. var date2 = time.Now() //结束时间
  545. var date3 = date2.Unix() - date1.Unix() //时间差的毫秒数
  546. //计算出相差天数
  547. var days = math.Floor(float64(date3 / (24 * 3600)))
  548. //计算出小时数
  549. var leave1 = date3 % (24 * 3600) //计算天数后剩余的毫秒数
  550. var hours = math.Floor(float64(leave1 / (3600)))
  551. //计算相差分钟数
  552. var leave2 = leave1 % (3600) //计算小时数后剩余的毫秒数
  553. var minutes = math.Floor(float64(leave2 / (60)))
  554. //计算相差秒数
  555. var td = "30秒前"
  556. if days > 0 {
  557. if days > 10 {
  558. if date1.Year() < date2.Year() {
  559. td = FormatDate(&date, Date_Short_Layout)
  560. } else {
  561. td = FormatDate(&date, Date_Small_Layout)
  562. }
  563. } else {
  564. td = fmt.Sprint(days) + "天前"
  565. }
  566. } else if hours > 0 {
  567. td = fmt.Sprint(hours) + "小时前"
  568. } else if minutes > 0 {
  569. td = fmt.Sprint(minutes) + "分钟前"
  570. }
  571. return td
  572. }
  573. func FloatFormat(tmp float64, n int) float64 {
  574. fs := fmt.Sprintf("%."+fmt.Sprint(n)+"f", tmp)
  575. f, _ := strconv.ParseFloat(fs, 64)
  576. return f
  577. }
  578. //生成微信支付的签名
  579. func CreateWxSign(afterStr string, obj interface{}, filter ...string) string {
  580. filter = append(filter, "sign", "xml")
  581. keys := []string{}
  582. m := make(map[string]string)
  583. t := reflect.TypeOf(obj)
  584. v := reflect.ValueOf(obj)
  585. k := t.Kind()
  586. if t.Kind() == reflect.Ptr {
  587. t = t.Elem()
  588. k = t.Kind()
  589. v = v.Elem()
  590. }
  591. if k == reflect.Map {
  592. for _, key := range v.MapKeys() {
  593. keys = append(keys, key.String())
  594. m[key.String()] = fmt.Sprint(v.MapIndex(key).Interface())
  595. }
  596. } else if k == reflect.Struct {
  597. for n := 0; n < t.NumField(); n++ {
  598. tagName := t.Field(n).Tag.Get("xml")
  599. if tagName == "" {
  600. tagName = t.Field(n).Tag.Get("json")
  601. }
  602. if tagName == "" {
  603. tagName = t.Field(n).Name
  604. }
  605. keys = append(keys, tagName)
  606. m[tagName] = fmt.Sprint(v.Field(n))
  607. }
  608. }
  609. sort.Strings(keys)
  610. vs := []string{}
  611. L:
  612. for _, v := range keys {
  613. for _, f := range filter {
  614. if f == v {
  615. continue L
  616. }
  617. }
  618. if strings.TrimSpace(m[v]) == "" {
  619. continue
  620. }
  621. vs = append(vs, fmt.Sprintf("%s=%s", v, m[v]))
  622. }
  623. return WxSign(strings.Join(vs, "&") + afterStr)
  624. }
  625. //简单的xml转map,只有一个层级,没有多层嵌套
  626. func XmlToMap(input string) map[string]string {
  627. var t xml.Token
  628. var err error
  629. inputReader := strings.NewReader(input)
  630. decoder := xml.NewDecoder(inputReader)
  631. isStart := false
  632. nodeName := ""
  633. m := make(map[string]string)
  634. for t, err = decoder.Token(); err == nil; t, err = decoder.Token() {
  635. switch token := t.(type) {
  636. // 处理元素开始(标签)
  637. case xml.StartElement:
  638. isStart = true
  639. nodeName = token.Name.Local
  640. // 处理元素结束(标签)
  641. case xml.EndElement:
  642. isStart = false
  643. // 处理字符数据(这里就是元素的文本)
  644. case xml.CharData:
  645. if isStart {
  646. m[nodeName] = string([]byte(token))
  647. }
  648. default:
  649. // ...
  650. }
  651. }
  652. return m
  653. }