| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709 |
- package public
- import (
- "bytes"
- "crypto"
- "crypto/aes"
- "crypto/cipher"
- "crypto/hmac"
- "crypto/md5"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/sha256"
- "crypto/sha512"
- "crypto/x509"
- "encoding/base64"
- "encoding/hex"
- "encoding/json"
- "encoding/pem"
- "errors"
- "fmt"
- "io"
- "math"
- mathRand "math/rand"
- "net/http"
- "net/url"
- "regexp"
- "strconv"
- "strings"
- "time"
- "unsafe"
- "golang.org/x/crypto/sha3"
- "bet24.com/log"
- "github.com/axgle/mahonia"
- )
- func ConvertToString(src string, srcCode string, tagCode string) string {
- srcCoder := mahonia.NewDecoder(srcCode)
- srcResult := srcCoder.ConvertString(src)
- tagCoder := mahonia.NewEncoder(tagCode)
- return tagCoder.ConvertString(srcResult)
- }
- func GetUtf8(src string) string {
- return ConvertToString(src, "GB18030", "UTF-8")
- }
- func GetGBK(src string) string {
- return ConvertToString(src, "UTF-8", "GB18030")
- }
- const ENCRYPT_KEY_LENGTH = 10
- func DecryptDBString(src string) string {
- lpszIn := []byte(src)
- if len(lpszIn) >= ENCRYPT_KEY_LENGTH*4 {
- szSoureLengthBuf := string([]byte{lpszIn[0], lpszIn[1]})
- nSoureLength64, _ := strconv.ParseInt(szSoureLengthBuf, 16, 0)
- nSoureLength := int(nSoureLength64)
- lpszOut := make([]byte, nSoureLength)
- for i := 0; i < nSoureLength; i++ {
- szKeyBuffer := string([]byte{lpszIn[i*4], lpszIn[i*4+1]})
- szEncryptBuffer := string([]byte{lpszIn[i*4+2], lpszIn[i*4+3]})
- uKey64, _ := strconv.ParseInt(szKeyBuffer, 16, 0)
- uEncrypt64, _ := strconv.ParseInt(szEncryptBuffer, 16, 0)
- uKey := uint8(uKey64)
- uEncrypt := uint8(uEncrypt64)
- lpszOut[i] = uKey ^ uEncrypt
- }
- return string(lpszOut)
- }
- return src
- }
- func StringIpToInt(ipstring string) uint32 {
- ipSegs := strings.Split(ipstring, ".")
- var ipInt int = 0
- var pos uint = 0
- for _, ipSeg := range ipSegs {
- tempInt, _ := strconv.Atoi(ipSeg)
- tempInt = tempInt << pos
- ipInt = ipInt + tempInt
- pos += 8
- }
- //fmt.Println("StringIpToInt", ipstring, ipInt)
- return uint32(ipInt)
- }
- func IpIntToString(ipInt uint32) string {
- ipSegs := make([]string, 4)
- var len int = len(ipSegs)
- buffer := bytes.NewBufferString("")
- for i := 0; i < len; i++ {
- tempInt := ipInt & 0xFF
- ipSegs[len-i-1] = strconv.Itoa(int(tempInt))
- ipInt = ipInt >> 8
- }
- for i := 0; i < len; i++ {
- buffer.WriteString(ipSegs[i])
- if i < len-1 {
- buffer.WriteString(".")
- }
- }
- return buffer.String()
- }
- // md5加密方式
- func GetMd5String(s string) string {
- h := md5.New()
- h.Write([]byte(s))
- return hex.EncodeToString(h.Sum(nil))
- }
- func HmacSHA1(key string, data string) string {
- mac := hmac.New(sha1.New, []byte(key))
- mac.Write([]byte(data))
- return hex.EncodeToString(mac.Sum(nil))
- }
- func HmacSHA256(key, data string) string {
- mac := hmac.New(sha256.New, []byte(key))
- mac.Write([]byte(data))
- return hex.EncodeToString(mac.Sum(nil))
- }
- func SHA256(data string) string {
- hash := sha256.New()
- hash.Write([]byte(data))
- hashed := hash.Sum(nil)
- return hex.EncodeToString(hashed)
- }
- func HmacSHA512(key, data string) string {
- mac := hmac.New(sha512.New, []byte(key))
- mac.Write([]byte(data))
- return hex.EncodeToString(mac.Sum(nil))
- }
- func Hmac_SHA3_SHA512(key, data string) string {
- mac := hmac.New(sha3.New512, []byte(key))
- mac.Write([]byte(data))
- return hex.EncodeToString(mac.Sum(nil))
- }
- // base64编码
- func Base64EncodeStr(src string) string {
- return string(base64.StdEncoding.EncodeToString([]byte(src)))
- }
- // base64解码
- func Base64DecodeStr(src string) string {
- a, err := base64.StdEncoding.DecodeString(src)
- if err != nil {
- return ""
- }
- return string(a)
- }
- // 加密数据
- func AesEncrypt(origData, key []byte) ([]byte, error) {
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
- blockSize := block.BlockSize()
- origData = PKCS5Padding(origData, blockSize)
- blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
- crypted := make([]byte, len(origData))
- blockMode.CryptBlocks(crypted, origData)
- return crypted, nil
- }
- // 解密数据
- func AesDecrypt(crypted, key []byte) ([]byte, error) {
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
- blockSize := block.BlockSize()
- blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
- origData := make([]byte, len(crypted))
- blockMode.CryptBlocks(origData, crypted)
- origData = PKCS5UnPadding(origData)
- return origData, nil
- }
- // 加密解密需要数据一定的格式, 如果愿数据不符合要求,需要加一些padding
- func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
- padding := blockSize - len(ciphertext)%blockSize
- padtext := bytes.Repeat([]byte{byte(padding)}, padding)
- return append(ciphertext, padtext...)
- }
- // 加密解密需要数据一定的格式, 如果愿数据不符合要求,需要加一些padding
- func PKCS5UnPadding(origData []byte) []byte {
- length := len(origData)
- unpadding := int(origData[length-1])
- return origData[:(length - unpadding)]
- }
- // 根据经纬度计算两点之间距离(米)
- func GetDistance(lat1, lng1, lat2, lng2 float64) float64 {
- radius := 6378137.0 //赤道半径
- rad := math.Pi / 180.0
- lat1 = lat1 * rad
- lng1 = lng1 * rad
- lat2 = lat2 * rad
- lng2 = lng2 * rad
- theta := lng2 - lng1
- dist := math.Acos(math.Sin(lat1)*math.Sin(lat2) + math.Cos(lat1)*math.Cos(lat2)*math.Cos(theta))
- return dist * radius
- }
- // HttpSMSCode请求并获取返回信息
- func HttpSMSCode(number, smsSendMsg, authSecret, smsPostUrl, code string) (string, error) {
- //发送的验证码短息内容
- sendMsg := fmt.Sprintf(smsSendMsg, code)
- //设置提交数据
- data := struct {
- AuthSecret string `json:"authSecret"`
- Number string `json:"number"`
- Sms string `json:"sms"`
- }{
- AuthSecret: authSecret,
- Number: number,
- Sms: sendMsg,
- }
- buf, _ := json.Marshal(data)
- msg := string(buf)
- log.Debug("httpSMSCode data=%s", msg)
- //请求
- body := HttpPostByJson(smsPostUrl, msg)
- //打印返回文本
- return string(body), nil
- }
- // HttpSMSSend请求并获取返回信息
- func HttpSMSSend(phone, smsSendMsg, smsAppID, smsApiKey, smsPostUrl string) (string, error) {
- if phone == "" || smsSendMsg == "" || smsAppID == "" || smsApiKey == "" || smsPostUrl == "" {
- return "空信息", nil
- }
- client := http.Client{}
- // 设置提交数据
- data := fmt.Sprintf("account=%v&password=%v&mobile=%v&content=%v",
- smsAppID, smsApiKey, phone, smsSendMsg)
- log.Debug("httpPostSMSCode data=%v", data)
- // 请求
- request, err := http.NewRequest("POST", smsPostUrl, strings.NewReader(data))
- if err != nil {
- log.Release("httpPostSMSCode send Request failer err=%v", err)
- return "", err // handle error
- }
- // 设置Content-Type
- request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- response, err := client.Do(request) // 返回
- if err != nil {
- log.Release("httpPostSMSCode client.Do return failer err=%v", err)
- return "", err
- }
- defer response.Body.Close()
- body, err := io.ReadAll(response.Body)
- if err != nil {
- return "", err
- }
- // 打印返回文本
- log.Debug(string(body))
- return string(body), nil
- }
- // HttpWithdraw请求提现并获取返回信息
- func HttpWithdraw(postUrl, data string) (string, error) {
- //log.Debug("HttpWithdraw postUrl=%s data=%s", postUrl, data)
- client := http.Client{}
- //请求
- request, err := http.NewRequest("POST", postUrl, strings.NewReader(data))
- //request, err := http.NewRequest("GET", url, nil)
- if err != nil {
- log.Release("HttpWithdraw send Request failer err=%v", err)
- return "", err // handle error
- }
- //设置Content-Type
- request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- response, err := client.Do(request) //返回
- if err != nil {
- log.Release("HttpWithdraw client.Do return failer err=%v", err)
- return "", err
- }
- defer response.Body.Close()
- body, err := io.ReadAll(response.Body)
- if err != nil {
- return "", err
- }
- //打印返回文本
- //log.Debug(string(body))
- return string(body), nil
- }
- // 检查手机号并返回手机号
- func CheckTelValid(tel string) (string, error) {
- reg := regexp.MustCompile(`^(\()?(\+62|62|0)(\d{2,3})?\)?[ .-]?\d{2,4}[ .-]?\d{2,4}[ .-]?\d{2,4}$`)
- matchs := reg.FindStringSubmatch(tel)
- if len(matchs) <= 0 {
- errString := fmt.Sprintf("tel format fail %s", tel)
- return "", errors.New(errString)
- }
- return tel, nil
- }
- func Sha256WithRsa(source, secret string) string {
- decodeString, err := base64.StdEncoding.DecodeString(secret)
- if err != nil {
- panic(err)
- }
- private, err := x509.ParsePKCS8PrivateKey(decodeString)
- if err != nil {
- panic(err)
- }
- //h := crypto.Hash.New(crypto.SHA256)
- h := sha256.New()
- h.Write([]byte(source))
- hashed := h.Sum(nil)
- signature, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey),
- crypto.SHA256, hashed)
- if err != nil {
- panic(err)
- }
- return base64.StdEncoding.EncodeToString(signature)
- }
- // 根据SHA256WithRSA算法获取签名对象实例
- func VerifyRsaSignBySHA256(content string, sign string, publicKey string) error {
- publicKeyByte, err := base64.StdEncoding.DecodeString(publicKey)
- if err != nil {
- return err
- }
- pub, err := x509.ParsePKIXPublicKey(publicKeyByte)
- if err != nil {
- return err
- }
- hashed := sha256.Sum256([]byte(content))
- signature, err := base64.StdEncoding.DecodeString(sign)
- if err != nil {
- return err
- }
- return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA256, hashed[:], signature)
- }
- // 根据SHA1WithRSA算法获取签名对象实例
- func VerifyRsaSignBySHA1(content string, sign string, publicKey string) error {
- publicKeyByte, err := base64.StdEncoding.DecodeString(publicKey)
- if err != nil {
- return err
- }
- pub, err := x509.ParsePKIXPublicKey(publicKeyByte)
- if err != nil {
- return err
- }
- hashed := sha1.Sum([]byte(content))
- signature, err := base64.StdEncoding.DecodeString(sign)
- if err != nil {
- return err
- }
- return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA1, hashed[:], signature)
- }
- func CheckMobile(phone string) bool {
- // 匹配规则
- // ^1第一位为一
- // [345789]{1} 后接一位345789 的数字
- // \\d \d的转义 表示数字 {9} 接9位
- // $ 结束符
- regRuler := "^1[345789]{1}\\d{9}$"
- // 正则调用规则
- reg := regexp.MustCompile(regRuler)
- // 返回 MatchString 是否匹配
- return reg.MatchString(phone)
- }
- const (
- letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
- // 6 bits to represent a letter index
- letterIdBits = 6
- // All 1-bits as many as letterIdBits
- letterIdMask = 1<<letterIdBits - 1
- letterIdMax = 63 / letterIdBits
- )
- // 指定随机的字符串
- func RandStr(n int) string {
- var src = mathRand.NewSource(time.Now().UnixNano())
- b := make([]byte, n)
- // A rand.Int63() generates 63 random bits, enough for letterIdMax letters!
- for i, cache, remain := n-1, src.Int63(), letterIdMax; i >= 0; {
- if remain == 0 {
- cache, remain = src.Int63(), letterIdMax
- }
- if idx := int(cache & letterIdMask); idx < len(letters) {
- b[i] = letters[idx]
- i--
- }
- cache >>= letterIdBits
- remain--
- }
- return *(*string)(unsafe.Pointer(&b))
- }
- // 解密【模拟了Java SHA1PRNG处理】
- func Sha1Decrypt(data, key string) (string, error) {
- dataByte, _ := Hex2bin(data)
- keys, err := AesSha1prng([]byte(key), 128)
- if err != nil {
- return "", err
- }
- block, err := aes.NewCipher(generateKey(keys))
- if err != nil {
- return "", err
- }
- decrypted := make([]byte, len(dataByte))
- size := block.BlockSize()
- for bs, be := 0, size; bs < len(dataByte); bs, be = bs+size, be+size {
- block.Decrypt(decrypted[bs:be], dataByte[bs:be])
- }
- decrypted = PKCS5UnPadding(decrypted)
- return string(decrypted), nil
- }
- // 加密【模拟了Java SHA1PRNG处理】
- func Sha1Encrypt(data, key []byte) (string, error) {
- keys, err := AesSha1prng(key, 128)
- if err != nil {
- return "", err
- }
- block, err := aes.NewCipher(generateKey(keys))
- if err != nil {
- return "", err
- }
- data = PKCS5Padding(data, block.BlockSize())
- decrypted := make([]byte, len(data))
- size := block.BlockSize()
- for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
- block.Encrypt(decrypted[bs:be], data[bs:be])
- }
- return Bin2hex(decrypted), nil
- }
- // 模拟java SHA1PRNG 处理
- func AesSha1prng(keyBytes []byte, encryptLength int) ([]byte, error) {
- hashs := Sha1(Sha1(keyBytes))
- maxLen := len(hashs)
- realLen := encryptLength / 8
- if realLen > maxLen {
- return nil, errors.New("invalid length")
- }
- return hashs[0:realLen], nil
- }
- func Sha1(data []byte) []byte {
- h := sha1.New()
- h.Write(data)
- bs := h.Sum(nil)
- h.Reset()
- return bs
- }
- // 生成密钥
- func generateKey(key []byte) (genKey []byte) {
- genKey = make([]byte, 16)
- copy(genKey, key)
- for i := 16; i < len(key); {
- for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
- genKey[j] ^= key[i]
- }
- }
- return genKey
- }
- func Bin2hex(b []byte) string {
- return base64.StdEncoding.EncodeToString(b)
- }
- func Hex2bin(x string) ([]byte, error) {
- return base64.StdEncoding.DecodeString(x)
- }
- // MD5withRSA 签名
- func MD5withRSASign(params url.Values, keys string) error {
- quUrl, err := url.QueryUnescape(params.Encode())
- if err != nil {
- return err
- }
- out, err := rsaSignWithMd5(quUrl, keys)
- if err != nil {
- return err
- }
- params.Add("sign", out)
- return nil
- }
- // 签名开始
- func rsaSignWithMd5(data string, prvKey string) (sign string, err error) {
- //如果密钥是urlSafeBase64的话需要处理下
- prvKey = Base64URLDecode(prvKey)
- keyBytes, err := base64.StdEncoding.DecodeString(prvKey)
- if err != nil {
- return "", err
- }
- privateKey, err := x509.ParsePKCS8PrivateKey(keyBytes)
- if err != nil {
- return "", err
- }
- h := md5.New()
- h.Write([]byte(data))
- hash := h.Sum(nil)
- signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.MD5, hash[:])
- if err != nil {
- return "", err
- }
- out := base64.RawURLEncoding.EncodeToString(signature)
- return out, nil
- }
- // 验签(MD5withRSA)
- func VerifyMD5withRSA(params url.Values, key string) error {
- sign := params.Get("sign")
- params.Del("sign")
- quUrl, _ := url.QueryUnescape(params.Encode())
- return rsaVerifySignWithMd5(quUrl, sign, key)
- }
- // 验签开始
- func rsaVerifySignWithMd5(originalData, signData, pubKey string) error {
- sign, err := base64.RawURLEncoding.DecodeString(signData)
- if err != nil {
- return err
- }
- pubKey = Base64URLDecode(pubKey)
- public, err := base64.StdEncoding.DecodeString(pubKey)
- if err != nil {
- return err
- }
- pub, err := x509.ParsePKIXPublicKey(public)
- if err != nil {
- return err
- }
- hash := md5.New()
- hash.Write([]byte(originalData))
- return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.MD5, hash.Sum(nil), sign)
- }
- // MD5withRSA 解密
- func MD5withRSADecrypt(sign, privateKey string) string {
- key := chunkSplit(privateKey, 64, "\n")
- key = fmt.Sprintf("-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----", key)
- decodedBytes, err := base64.StdEncoding.DecodeString(sign)
- if err != nil {
- return ""
- }
- block, _ := pem.Decode([]byte(key))
- if block == nil {
- return ""
- }
- keys, err := x509.ParsePKCS8PrivateKey(block.Bytes)
- if err != nil {
- return ""
- }
- resCrypto := ""
- for _, v := range strSplit(string(decodedBytes), 128) {
- // 使用 RSA 私钥解密密文
- plaintext, errs := rsa.DecryptPKCS1v15(rand.Reader, keys.(*rsa.PrivateKey), []byte(v))
- if errs != nil {
- return ""
- }
- resCrypto += string(plaintext)
- }
- return resCrypto
- }
- // 字符串分割密文
- func strSplit(s string, chunkSize int) []string {
- var chunks []string
- for i := 0; i < len(s); i += chunkSize {
- end := i + chunkSize
- if end > len(s) {
- end = len(s)
- }
- chunks = append(chunks, s[i:end])
- }
- return chunks
- }
- // 块分割
- func chunkSplit(s string, chunkLen int, separator string) string {
- var result strings.Builder
- for i := 0; i < len(s); i += chunkLen {
- end := i + chunkLen
- if end > len(s) {
- end = len(s)
- }
- result.WriteString(s[i:end])
- if end < len(s) {
- result.WriteString(separator)
- }
- }
- return result.String()
- }
- //因为Base64转码后可能包含有+,/,=这些不安全的URL字符串,所以要进行换字符
- // '+' -> '-'
- // '/' -> '_'
- // '=' -> ''
- // 字符串长度不足4倍的位补"="
- func Base64URLDecode(data string) string {
- var missing = (4 - len(data)%4) % 4
- data += strings.Repeat("=", missing) //字符串长度不足4倍的位补"="
- data = strings.Replace(data, "_", "/", -1)
- data = strings.Replace(data, "-", "+", -1)
- return data
- }
- func Base64UrlSafeEncode(data string) string {
- safeUrl := strings.Replace(data, "/", "_", -1)
- safeUrl = strings.Replace(safeUrl, "+", "-", -1)
- safeUrl = strings.Replace(safeUrl, "=", "", -1)
- return safeUrl
- }
- // 生成码
- func GenCode(length int) string {
- var chars = []byte("ABCDEFGHJKLMNPQRTUVWXYZ123456789")
- code := make([]byte, length)
- clen := len(chars)
- for i := 0; i < length; i++ {
- index := mathRand.Intn(clen)
- code[i] = byte(chars[index])
- }
- return string(code)
- }
- // SlicePage 分页算法(pageIndex 页索引、pageSize 页大小、nums 总记录数)
- // exploreList := manager.Mgr.GetExploreList()
- //
- // totalCount := len(exploreList)
- // start, end := public.SlicePage(req.PageIndex, req.PageSize, totalCount)
- // rsp.RecordCount = totalCount
- // rsp.List = this.getOwnerList(exploreList[start:end])
- func SlicePage(pageIndex, pageSize, nums int) (start, end int) {
- if pageIndex <= 0 {
- pageIndex = 1
- }
- if pageSize < 0 {
- pageSize = 10
- }
- if pageSize > nums {
- return 0, nums
- }
- // 计算起始行
- start = (pageIndex - 1) * pageSize
- // 计算终止行
- end = start + pageSize
- if end > nums {
- end = nums
- }
- if start > end {
- return 0, 0
- }
- // 起始、终止位置
- return start, end
- }
|