blog_backend_api/vendor/git.jiaxianghudong.com/go/utils/coding.go

290 lines
5.8 KiB
Go
Raw Normal View History

2019-01-28 03:19:49 +00:00
package utils
import (
"encoding/json"
"strings"
"log"
"time"
"fmt"
"encoding/pem"
"crypto/x509"
"crypto/rsa"
"encoding/base64"
"errors"
"io"
"net/url"
"hash/crc32"
crand "crypto/rand"
"crypto/hmac"
"crypto/sha1"
"crypto/md5"
)
// md5
func Md5Sum(text string) string {
h := md5.New()
io.WriteString(h, text)
return fmt.Sprintf("%x", h.Sum(nil))
}
// 加解密函数 根据dz的Authcode改写的go版本
// params[0] 加密or解密 bool true加密 false解密 默认false
// params[1] 秘钥
// params[2] 加密:过期时间
// params[3] 动态秘钥长度 默认4位 不能大于32位
func Authcode(text string, params ...interface{}) string {
defer func() {
if err := recover(); err != nil {
log.Printf("authcode error:%#v", err)
}
}()
l := len(params)
isEncode := false
key := "DH-Framework"
expiry := 0
cKeyLen := 10
if l > 0 {
isEncode = params[0].(bool)
}
if l > 1 {
key = params[1].(string)
}
if l > 2 {
expiry = params[2].(int)
if expiry < 0 {
expiry = 0
}
}
if l > 3 {
cKeyLen = params[3].(int)
if cKeyLen < 0 {
cKeyLen = 0
}
}
if cKeyLen > 32 {
cKeyLen = 32
}
timestamp := time.Now().Unix()
// md5加密key
mKey := Md5Sum(key)
// 参与加密的
keyA := Md5Sum(mKey[0:16])
// 用于验证数据有效性的
keyB := Md5Sum(mKey[16:])
// 动态部分
var keyC string
if cKeyLen > 0 {
if isEncode {
// 加密的时候,动态获取一个秘钥
keyC = Md5Sum(fmt.Sprint(timestamp))[32 - cKeyLen:]
} else {
// 解密的时候从头部获取动态秘钥部分
keyC = text[0:cKeyLen]
}
}
// 加入了动态的秘钥
cryptKey := keyA + Md5Sum(keyA + keyC)
// 秘钥长度
keyLen := len(cryptKey)
if isEncode {
// 加密 前10位是过期验证字符串 10-26位字符串验证
var d int64
if expiry > 0 {
d = timestamp + int64(expiry)
}
text = fmt.Sprintf("%010d%s%s", d, Md5Sum(text + keyB)[0:16], text)
} else {
// 解密
text = string(Base64Decode(text[cKeyLen:]))
}
// 字符串长度
textLen := len(text)
if textLen <= 0 {
panic(fmt.Sprintf("auth[%s]textLen<=0", text))
}
// 密匙簿
box := Range(0, 256)
// 对称算法
var rndKey []int
cryptKeyB := []byte(cryptKey)
for i := 0; i < 256; i++ {
pos := i % keyLen
rndKey = append(rndKey, int(cryptKeyB[pos]))
}
j := 0
for i := 0; i < 256; i++ {
j = (j + box[i] + rndKey[i]) % 256
box[i], box[j] = box[j], box[i]
}
textB := []byte(text)
a := 0
j = 0
var result []byte
for i := 0; i < textLen; i++ {
a = (a + 1) % 256
j = (j + box[a]) % 256
box[a], box[j] = box[j], box[a]
result = append(result, byte(int(textB[i]) ^ (box[(box[a] + box[j]) % 256])))
}
if isEncode {
return keyC + strings.Replace(Base64Encode(result), "=", "", -1)
}
// 获取前10位判断过期时间
d := Atoi64(string(result[0:10]), 0)
if (d == 0 || d - timestamp > 0) && string(result[10:26]) == Md5Sum(string(result[26:]) + keyB)[0:16] {
return string(result[26:])
}
panic(fmt.Sprintf("auth[%s]", text))
return ""
}
// AuthcodeUrl 处理Authcode函数的加密解密结果以便url传输
func AuthcodeUrl(text string, params ...interface{}) string {
isEncode := false
if len(params) > 0 {
isEncode = params[0].(bool)
}
if isEncode { //加密
return strings.Replace(strings.Replace(Authcode(text, params...), "+", ",", -1), "/", "-", -1)
} else {
return Authcode(strings.Replace(strings.Replace(text, ",", "+", -1), "-", "/", -1), params...)
}
}
2019-01-31 08:57:22 +00:00
// JsonEncode 编码JSON
func JsonEncode(m interface{}) string {
2019-01-28 03:19:49 +00:00
b, err := json.Marshal(m)
if err != nil {
2019-01-31 08:57:22 +00:00
log.Printf("Json Encode[%#v] Error:%s", m, err.Error())
return ""
2019-01-28 03:19:49 +00:00
}
2019-01-31 08:57:22 +00:00
return string(b)
2019-01-28 03:19:49 +00:00
}
2019-01-31 08:57:22 +00:00
// JsonDecode 解码JSON
func JsonDecode(str string, v ...interface{}) (interface{}, error) {
2019-01-28 03:19:49 +00:00
var m interface{}
if len(v) > 0 {
m = v[0]
} else {
m = make(map[string]interface{})
}
err := json.Unmarshal([]byte(str), &m)
if err != nil {
return nil, err
}
return m, nil
}
func Crc32(text string) string {
h := crc32.NewIEEE()
io.WriteString(h, text)
return fmt.Sprintf("%d", h.Sum32())
}
// RsaEncode rsa加密
func RsaEncode(b, rsaKey []byte) ([]byte, error) {
block, _ := pem.Decode(rsaKey)
if block == nil {
return b, errors.New("key error")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return b, err
}
return rsa.EncryptPKCS1v15(crand.Reader, pub.(*rsa.PublicKey), b)
}
// RsaDecode rsa解密
func RsaDecode(b, rsaKey []byte) ([]byte, error) {
block, _ := pem.Decode(rsaKey)
if block == nil {
return b, errors.New("key error")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return b, err
}
return rsa.DecryptPKCS1v15(crand.Reader, priv, b)
}
func HashHmac(data, key string) string {
mac := hmac.New(sha1.New, []byte(key))
mac.Write([]byte(data))
return fmt.Sprintf("%x", mac.Sum(nil))
}
func HashHmacRaw(data, key string) string {
mac := hmac.New(sha1.New, []byte(key))
mac.Write([]byte(data))
return fmt.Sprintf("%s", mac.Sum(nil))
}
// Base64Encode Base64编码
func Base64Encode(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
}
// Base64Decode Base64解码
func Base64Decode(str string) []byte {
var b []byte
var err error
x := len(str) * 3 % 4
switch {
case x == 2:
str += "=="
case x == 1:
str += "="
}
if b, err = base64.StdEncoding.DecodeString(str); err != nil {
return b
}
return b
}
// UrlEncode 编码
func UrlEncode(str string) string {
return url.QueryEscape(str)
}
// UrlDecode 解码
func UrlDecode(str string) string {
ret, _ := url.QueryUnescape(str)
return ret
}
/*func Urlencode(str string) string {
return base64.URLEncoding.EncodeToString([]byte(str))
}
func Urldecode(str string) string {
b, e := base64.URLEncoding.DecodeString(str)
if e != nil {
log.Printf("urldecode error:%s", e.Error())
return ""
}
return string(b)
}*/