Public.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. package public
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/aes"
  6. "crypto/cipher"
  7. "crypto/hmac"
  8. "crypto/md5"
  9. "crypto/rand"
  10. "crypto/rsa"
  11. "crypto/sha1"
  12. "crypto/sha256"
  13. "crypto/sha512"
  14. "crypto/x509"
  15. "encoding/base64"
  16. "encoding/hex"
  17. "encoding/json"
  18. "encoding/pem"
  19. "errors"
  20. "fmt"
  21. "io"
  22. "math"
  23. mathRand "math/rand"
  24. "net/http"
  25. "net/url"
  26. "regexp"
  27. "strconv"
  28. "strings"
  29. "time"
  30. "unsafe"
  31. "golang.org/x/crypto/sha3"
  32. "bet24.com/log"
  33. "github.com/axgle/mahonia"
  34. )
  35. func ConvertToString(src string, srcCode string, tagCode string) string {
  36. srcCoder := mahonia.NewDecoder(srcCode)
  37. srcResult := srcCoder.ConvertString(src)
  38. tagCoder := mahonia.NewEncoder(tagCode)
  39. return tagCoder.ConvertString(srcResult)
  40. }
  41. func GetUtf8(src string) string {
  42. return ConvertToString(src, "GB18030", "UTF-8")
  43. }
  44. func GetGBK(src string) string {
  45. return ConvertToString(src, "UTF-8", "GB18030")
  46. }
  47. const ENCRYPT_KEY_LENGTH = 10
  48. func DecryptDBString(src string) string {
  49. lpszIn := []byte(src)
  50. if len(lpszIn) >= ENCRYPT_KEY_LENGTH*4 {
  51. szSoureLengthBuf := string([]byte{lpszIn[0], lpszIn[1]})
  52. nSoureLength64, _ := strconv.ParseInt(szSoureLengthBuf, 16, 0)
  53. nSoureLength := int(nSoureLength64)
  54. lpszOut := make([]byte, nSoureLength)
  55. for i := 0; i < nSoureLength; i++ {
  56. szKeyBuffer := string([]byte{lpszIn[i*4], lpszIn[i*4+1]})
  57. szEncryptBuffer := string([]byte{lpszIn[i*4+2], lpszIn[i*4+3]})
  58. uKey64, _ := strconv.ParseInt(szKeyBuffer, 16, 0)
  59. uEncrypt64, _ := strconv.ParseInt(szEncryptBuffer, 16, 0)
  60. uKey := uint8(uKey64)
  61. uEncrypt := uint8(uEncrypt64)
  62. lpszOut[i] = uKey ^ uEncrypt
  63. }
  64. return string(lpszOut)
  65. }
  66. return src
  67. }
  68. func StringIpToInt(ipstring string) uint32 {
  69. ipSegs := strings.Split(ipstring, ".")
  70. var ipInt int = 0
  71. var pos uint = 0
  72. for _, ipSeg := range ipSegs {
  73. tempInt, _ := strconv.Atoi(ipSeg)
  74. tempInt = tempInt << pos
  75. ipInt = ipInt + tempInt
  76. pos += 8
  77. }
  78. //fmt.Println("StringIpToInt", ipstring, ipInt)
  79. return uint32(ipInt)
  80. }
  81. func IpIntToString(ipInt uint32) string {
  82. ipSegs := make([]string, 4)
  83. var len int = len(ipSegs)
  84. buffer := bytes.NewBufferString("")
  85. for i := 0; i < len; i++ {
  86. tempInt := ipInt & 0xFF
  87. ipSegs[len-i-1] = strconv.Itoa(int(tempInt))
  88. ipInt = ipInt >> 8
  89. }
  90. for i := 0; i < len; i++ {
  91. buffer.WriteString(ipSegs[i])
  92. if i < len-1 {
  93. buffer.WriteString(".")
  94. }
  95. }
  96. return buffer.String()
  97. }
  98. // md5加密方式
  99. func GetMd5String(s string) string {
  100. h := md5.New()
  101. h.Write([]byte(s))
  102. return hex.EncodeToString(h.Sum(nil))
  103. }
  104. func HmacSHA1(key string, data string) string {
  105. mac := hmac.New(sha1.New, []byte(key))
  106. mac.Write([]byte(data))
  107. return hex.EncodeToString(mac.Sum(nil))
  108. }
  109. func HmacSHA256(key, data string) string {
  110. mac := hmac.New(sha256.New, []byte(key))
  111. mac.Write([]byte(data))
  112. return hex.EncodeToString(mac.Sum(nil))
  113. }
  114. func SHA256(data string) string {
  115. hash := sha256.New()
  116. hash.Write([]byte(data))
  117. hashed := hash.Sum(nil)
  118. return hex.EncodeToString(hashed)
  119. }
  120. func HmacSHA512(key, data string) string {
  121. mac := hmac.New(sha512.New, []byte(key))
  122. mac.Write([]byte(data))
  123. return hex.EncodeToString(mac.Sum(nil))
  124. }
  125. func Hmac_SHA3_SHA512(key, data string) string {
  126. mac := hmac.New(sha3.New512, []byte(key))
  127. mac.Write([]byte(data))
  128. return hex.EncodeToString(mac.Sum(nil))
  129. }
  130. // base64编码
  131. func Base64EncodeStr(src string) string {
  132. return string(base64.StdEncoding.EncodeToString([]byte(src)))
  133. }
  134. // base64解码
  135. func Base64DecodeStr(src string) string {
  136. a, err := base64.StdEncoding.DecodeString(src)
  137. if err != nil {
  138. return ""
  139. }
  140. return string(a)
  141. }
  142. // 加密数据
  143. func AesEncrypt(origData, key []byte) ([]byte, error) {
  144. block, err := aes.NewCipher(key)
  145. if err != nil {
  146. return nil, err
  147. }
  148. blockSize := block.BlockSize()
  149. origData = PKCS5Padding(origData, blockSize)
  150. blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
  151. crypted := make([]byte, len(origData))
  152. blockMode.CryptBlocks(crypted, origData)
  153. return crypted, nil
  154. }
  155. // 解密数据
  156. func AesDecrypt(crypted, key []byte) ([]byte, error) {
  157. block, err := aes.NewCipher(key)
  158. if err != nil {
  159. return nil, err
  160. }
  161. blockSize := block.BlockSize()
  162. blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
  163. origData := make([]byte, len(crypted))
  164. blockMode.CryptBlocks(origData, crypted)
  165. origData = PKCS5UnPadding(origData)
  166. return origData, nil
  167. }
  168. // 加密解密需要数据一定的格式, 如果愿数据不符合要求,需要加一些padding
  169. func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
  170. padding := blockSize - len(ciphertext)%blockSize
  171. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  172. return append(ciphertext, padtext...)
  173. }
  174. // 加密解密需要数据一定的格式, 如果愿数据不符合要求,需要加一些padding
  175. func PKCS5UnPadding(origData []byte) []byte {
  176. length := len(origData)
  177. unpadding := int(origData[length-1])
  178. return origData[:(length - unpadding)]
  179. }
  180. // 根据经纬度计算两点之间距离(米)
  181. func GetDistance(lat1, lng1, lat2, lng2 float64) float64 {
  182. radius := 6378137.0 //赤道半径
  183. rad := math.Pi / 180.0
  184. lat1 = lat1 * rad
  185. lng1 = lng1 * rad
  186. lat2 = lat2 * rad
  187. lng2 = lng2 * rad
  188. theta := lng2 - lng1
  189. dist := math.Acos(math.Sin(lat1)*math.Sin(lat2) + math.Cos(lat1)*math.Cos(lat2)*math.Cos(theta))
  190. return dist * radius
  191. }
  192. // HttpSMSCode请求并获取返回信息
  193. func HttpSMSCode(number, smsSendMsg, authSecret, smsPostUrl, code string) (string, error) {
  194. //发送的验证码短息内容
  195. sendMsg := fmt.Sprintf(smsSendMsg, code)
  196. //设置提交数据
  197. data := struct {
  198. AuthSecret string `json:"authSecret"`
  199. Number string `json:"number"`
  200. Sms string `json:"sms"`
  201. }{
  202. AuthSecret: authSecret,
  203. Number: number,
  204. Sms: sendMsg,
  205. }
  206. buf, _ := json.Marshal(data)
  207. msg := string(buf)
  208. log.Debug("httpSMSCode data=%s", msg)
  209. //请求
  210. body := HttpPostByJson(smsPostUrl, msg)
  211. //打印返回文本
  212. return string(body), nil
  213. }
  214. // HttpSMSSend请求并获取返回信息
  215. func HttpSMSSend(phone, smsSendMsg, smsAppID, smsApiKey, smsPostUrl string) (string, error) {
  216. if phone == "" || smsSendMsg == "" || smsAppID == "" || smsApiKey == "" || smsPostUrl == "" {
  217. return "空信息", nil
  218. }
  219. client := http.Client{}
  220. // 设置提交数据
  221. data := fmt.Sprintf("account=%v&password=%v&mobile=%v&content=%v",
  222. smsAppID, smsApiKey, phone, smsSendMsg)
  223. log.Debug("httpPostSMSCode data=%v", data)
  224. // 请求
  225. request, err := http.NewRequest("POST", smsPostUrl, strings.NewReader(data))
  226. if err != nil {
  227. log.Release("httpPostSMSCode send Request failer err=%v", err)
  228. return "", err // handle error
  229. }
  230. // 设置Content-Type
  231. request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
  232. response, err := client.Do(request) // 返回
  233. if err != nil {
  234. log.Release("httpPostSMSCode client.Do return failer err=%v", err)
  235. return "", err
  236. }
  237. defer response.Body.Close()
  238. body, err := io.ReadAll(response.Body)
  239. if err != nil {
  240. return "", err
  241. }
  242. // 打印返回文本
  243. log.Debug(string(body))
  244. return string(body), nil
  245. }
  246. // HttpWithdraw请求提现并获取返回信息
  247. func HttpWithdraw(postUrl, data string) (string, error) {
  248. //log.Debug("HttpWithdraw postUrl=%s data=%s", postUrl, data)
  249. client := http.Client{}
  250. //请求
  251. request, err := http.NewRequest("POST", postUrl, strings.NewReader(data))
  252. //request, err := http.NewRequest("GET", url, nil)
  253. if err != nil {
  254. log.Release("HttpWithdraw send Request failer err=%v", err)
  255. return "", err // handle error
  256. }
  257. //设置Content-Type
  258. request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
  259. response, err := client.Do(request) //返回
  260. if err != nil {
  261. log.Release("HttpWithdraw client.Do return failer err=%v", err)
  262. return "", err
  263. }
  264. defer response.Body.Close()
  265. body, err := io.ReadAll(response.Body)
  266. if err != nil {
  267. return "", err
  268. }
  269. //打印返回文本
  270. //log.Debug(string(body))
  271. return string(body), nil
  272. }
  273. // 检查手机号并返回手机号
  274. func CheckTelValid(tel string) (string, error) {
  275. reg := regexp.MustCompile(`^(\()?(\+62|62|0)(\d{2,3})?\)?[ .-]?\d{2,4}[ .-]?\d{2,4}[ .-]?\d{2,4}$`)
  276. matchs := reg.FindStringSubmatch(tel)
  277. if len(matchs) <= 0 {
  278. errString := fmt.Sprintf("tel format fail %s", tel)
  279. return "", errors.New(errString)
  280. }
  281. return tel, nil
  282. }
  283. func Sha256WithRsa(source, secret string) string {
  284. decodeString, err := base64.StdEncoding.DecodeString(secret)
  285. if err != nil {
  286. panic(err)
  287. }
  288. private, err := x509.ParsePKCS8PrivateKey(decodeString)
  289. if err != nil {
  290. panic(err)
  291. }
  292. //h := crypto.Hash.New(crypto.SHA256)
  293. h := sha256.New()
  294. h.Write([]byte(source))
  295. hashed := h.Sum(nil)
  296. signature, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey),
  297. crypto.SHA256, hashed)
  298. if err != nil {
  299. panic(err)
  300. }
  301. return base64.StdEncoding.EncodeToString(signature)
  302. }
  303. // 根据SHA256WithRSA算法获取签名对象实例
  304. func VerifyRsaSignBySHA256(content string, sign string, publicKey string) error {
  305. publicKeyByte, err := base64.StdEncoding.DecodeString(publicKey)
  306. if err != nil {
  307. return err
  308. }
  309. pub, err := x509.ParsePKIXPublicKey(publicKeyByte)
  310. if err != nil {
  311. return err
  312. }
  313. hashed := sha256.Sum256([]byte(content))
  314. signature, err := base64.StdEncoding.DecodeString(sign)
  315. if err != nil {
  316. return err
  317. }
  318. return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA256, hashed[:], signature)
  319. }
  320. // 根据SHA1WithRSA算法获取签名对象实例
  321. func VerifyRsaSignBySHA1(content string, sign string, publicKey string) error {
  322. publicKeyByte, err := base64.StdEncoding.DecodeString(publicKey)
  323. if err != nil {
  324. return err
  325. }
  326. pub, err := x509.ParsePKIXPublicKey(publicKeyByte)
  327. if err != nil {
  328. return err
  329. }
  330. hashed := sha1.Sum([]byte(content))
  331. signature, err := base64.StdEncoding.DecodeString(sign)
  332. if err != nil {
  333. return err
  334. }
  335. return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA1, hashed[:], signature)
  336. }
  337. func CheckMobile(phone string) bool {
  338. // 匹配规则
  339. // ^1第一位为一
  340. // [345789]{1} 后接一位345789 的数字
  341. // \\d \d的转义 表示数字 {9} 接9位
  342. // $ 结束符
  343. regRuler := "^1[345789]{1}\\d{9}$"
  344. // 正则调用规则
  345. reg := regexp.MustCompile(regRuler)
  346. // 返回 MatchString 是否匹配
  347. return reg.MatchString(phone)
  348. }
  349. const (
  350. letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  351. // 6 bits to represent a letter index
  352. letterIdBits = 6
  353. // All 1-bits as many as letterIdBits
  354. letterIdMask = 1<<letterIdBits - 1
  355. letterIdMax = 63 / letterIdBits
  356. )
  357. // 指定随机的字符串
  358. func RandStr(n int) string {
  359. var src = mathRand.NewSource(time.Now().UnixNano())
  360. b := make([]byte, n)
  361. // A rand.Int63() generates 63 random bits, enough for letterIdMax letters!
  362. for i, cache, remain := n-1, src.Int63(), letterIdMax; i >= 0; {
  363. if remain == 0 {
  364. cache, remain = src.Int63(), letterIdMax
  365. }
  366. if idx := int(cache & letterIdMask); idx < len(letters) {
  367. b[i] = letters[idx]
  368. i--
  369. }
  370. cache >>= letterIdBits
  371. remain--
  372. }
  373. return *(*string)(unsafe.Pointer(&b))
  374. }
  375. // 解密【模拟了Java SHA1PRNG处理】
  376. func Sha1Decrypt(data, key string) (string, error) {
  377. dataByte, _ := Hex2bin(data)
  378. keys, err := AesSha1prng([]byte(key), 128)
  379. if err != nil {
  380. return "", err
  381. }
  382. block, err := aes.NewCipher(generateKey(keys))
  383. if err != nil {
  384. return "", err
  385. }
  386. decrypted := make([]byte, len(dataByte))
  387. size := block.BlockSize()
  388. for bs, be := 0, size; bs < len(dataByte); bs, be = bs+size, be+size {
  389. block.Decrypt(decrypted[bs:be], dataByte[bs:be])
  390. }
  391. decrypted = PKCS5UnPadding(decrypted)
  392. return string(decrypted), nil
  393. }
  394. // 加密【模拟了Java SHA1PRNG处理】
  395. func Sha1Encrypt(data, key []byte) (string, error) {
  396. keys, err := AesSha1prng(key, 128)
  397. if err != nil {
  398. return "", err
  399. }
  400. block, err := aes.NewCipher(generateKey(keys))
  401. if err != nil {
  402. return "", err
  403. }
  404. data = PKCS5Padding(data, block.BlockSize())
  405. decrypted := make([]byte, len(data))
  406. size := block.BlockSize()
  407. for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
  408. block.Encrypt(decrypted[bs:be], data[bs:be])
  409. }
  410. return Bin2hex(decrypted), nil
  411. }
  412. // 模拟java SHA1PRNG 处理
  413. func AesSha1prng(keyBytes []byte, encryptLength int) ([]byte, error) {
  414. hashs := Sha1(Sha1(keyBytes))
  415. maxLen := len(hashs)
  416. realLen := encryptLength / 8
  417. if realLen > maxLen {
  418. return nil, errors.New("invalid length")
  419. }
  420. return hashs[0:realLen], nil
  421. }
  422. func Sha1(data []byte) []byte {
  423. h := sha1.New()
  424. h.Write(data)
  425. bs := h.Sum(nil)
  426. h.Reset()
  427. return bs
  428. }
  429. // 生成密钥
  430. func generateKey(key []byte) (genKey []byte) {
  431. genKey = make([]byte, 16)
  432. copy(genKey, key)
  433. for i := 16; i < len(key); {
  434. for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
  435. genKey[j] ^= key[i]
  436. }
  437. }
  438. return genKey
  439. }
  440. func Bin2hex(b []byte) string {
  441. return base64.StdEncoding.EncodeToString(b)
  442. }
  443. func Hex2bin(x string) ([]byte, error) {
  444. return base64.StdEncoding.DecodeString(x)
  445. }
  446. // MD5withRSA 签名
  447. func MD5withRSASign(params url.Values, keys string) error {
  448. quUrl, err := url.QueryUnescape(params.Encode())
  449. if err != nil {
  450. return err
  451. }
  452. out, err := rsaSignWithMd5(quUrl, keys)
  453. if err != nil {
  454. return err
  455. }
  456. params.Add("sign", out)
  457. return nil
  458. }
  459. // 签名开始
  460. func rsaSignWithMd5(data string, prvKey string) (sign string, err error) {
  461. //如果密钥是urlSafeBase64的话需要处理下
  462. prvKey = Base64URLDecode(prvKey)
  463. keyBytes, err := base64.StdEncoding.DecodeString(prvKey)
  464. if err != nil {
  465. return "", err
  466. }
  467. privateKey, err := x509.ParsePKCS8PrivateKey(keyBytes)
  468. if err != nil {
  469. return "", err
  470. }
  471. h := md5.New()
  472. h.Write([]byte(data))
  473. hash := h.Sum(nil)
  474. signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.MD5, hash[:])
  475. if err != nil {
  476. return "", err
  477. }
  478. out := base64.RawURLEncoding.EncodeToString(signature)
  479. return out, nil
  480. }
  481. // 验签(MD5withRSA)
  482. func VerifyMD5withRSA(params url.Values, key string) error {
  483. sign := params.Get("sign")
  484. params.Del("sign")
  485. quUrl, _ := url.QueryUnescape(params.Encode())
  486. return rsaVerifySignWithMd5(quUrl, sign, key)
  487. }
  488. // 验签开始
  489. func rsaVerifySignWithMd5(originalData, signData, pubKey string) error {
  490. sign, err := base64.RawURLEncoding.DecodeString(signData)
  491. if err != nil {
  492. return err
  493. }
  494. pubKey = Base64URLDecode(pubKey)
  495. public, err := base64.StdEncoding.DecodeString(pubKey)
  496. if err != nil {
  497. return err
  498. }
  499. pub, err := x509.ParsePKIXPublicKey(public)
  500. if err != nil {
  501. return err
  502. }
  503. hash := md5.New()
  504. hash.Write([]byte(originalData))
  505. return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.MD5, hash.Sum(nil), sign)
  506. }
  507. // MD5withRSA 解密
  508. func MD5withRSADecrypt(sign, privateKey string) string {
  509. key := chunkSplit(privateKey, 64, "\n")
  510. key = fmt.Sprintf("-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----", key)
  511. decodedBytes, err := base64.StdEncoding.DecodeString(sign)
  512. if err != nil {
  513. return ""
  514. }
  515. block, _ := pem.Decode([]byte(key))
  516. if block == nil {
  517. return ""
  518. }
  519. keys, err := x509.ParsePKCS8PrivateKey(block.Bytes)
  520. if err != nil {
  521. return ""
  522. }
  523. resCrypto := ""
  524. for _, v := range strSplit(string(decodedBytes), 128) {
  525. // 使用 RSA 私钥解密密文
  526. plaintext, errs := rsa.DecryptPKCS1v15(rand.Reader, keys.(*rsa.PrivateKey), []byte(v))
  527. if errs != nil {
  528. return ""
  529. }
  530. resCrypto += string(plaintext)
  531. }
  532. return resCrypto
  533. }
  534. // 字符串分割密文
  535. func strSplit(s string, chunkSize int) []string {
  536. var chunks []string
  537. for i := 0; i < len(s); i += chunkSize {
  538. end := i + chunkSize
  539. if end > len(s) {
  540. end = len(s)
  541. }
  542. chunks = append(chunks, s[i:end])
  543. }
  544. return chunks
  545. }
  546. // 块分割
  547. func chunkSplit(s string, chunkLen int, separator string) string {
  548. var result strings.Builder
  549. for i := 0; i < len(s); i += chunkLen {
  550. end := i + chunkLen
  551. if end > len(s) {
  552. end = len(s)
  553. }
  554. result.WriteString(s[i:end])
  555. if end < len(s) {
  556. result.WriteString(separator)
  557. }
  558. }
  559. return result.String()
  560. }
  561. //因为Base64转码后可能包含有+,/,=这些不安全的URL字符串,所以要进行换字符
  562. // '+' -> '-'
  563. // '/' -> '_'
  564. // '=' -> ''
  565. // 字符串长度不足4倍的位补"="
  566. func Base64URLDecode(data string) string {
  567. var missing = (4 - len(data)%4) % 4
  568. data += strings.Repeat("=", missing) //字符串长度不足4倍的位补"="
  569. data = strings.Replace(data, "_", "/", -1)
  570. data = strings.Replace(data, "-", "+", -1)
  571. return data
  572. }
  573. func Base64UrlSafeEncode(data string) string {
  574. safeUrl := strings.Replace(data, "/", "_", -1)
  575. safeUrl = strings.Replace(safeUrl, "+", "-", -1)
  576. safeUrl = strings.Replace(safeUrl, "=", "", -1)
  577. return safeUrl
  578. }
  579. // 生成码
  580. func GenCode(length int) string {
  581. var chars = []byte("ABCDEFGHJKLMNPQRTUVWXYZ123456789")
  582. code := make([]byte, length)
  583. clen := len(chars)
  584. for i := 0; i < length; i++ {
  585. index := mathRand.Intn(clen)
  586. code[i] = byte(chars[index])
  587. }
  588. return string(code)
  589. }
  590. // SlicePage 分页算法(pageIndex 页索引、pageSize 页大小、nums 总记录数)
  591. // exploreList := manager.Mgr.GetExploreList()
  592. //
  593. // totalCount := len(exploreList)
  594. // start, end := public.SlicePage(req.PageIndex, req.PageSize, totalCount)
  595. // rsp.RecordCount = totalCount
  596. // rsp.List = this.getOwnerList(exploreList[start:end])
  597. func SlicePage(pageIndex, pageSize, nums int) (start, end int) {
  598. if pageIndex <= 0 {
  599. pageIndex = 1
  600. }
  601. if pageSize < 0 {
  602. pageSize = 10
  603. }
  604. if pageSize > nums {
  605. return 0, nums
  606. }
  607. // 计算起始行
  608. start = (pageIndex - 1) * pageSize
  609. // 计算终止行
  610. end = start + pageSize
  611. if end > nums {
  612. end = nums
  613. }
  614. if start > end {
  615. return 0, 0
  616. }
  617. // 起始、终止位置
  618. return start, end
  619. }