package base import ( "crypto/sha512" "encoding/json" "fmt" "net/url" "reflect" "sort" "strings" "github.com/gin-gonic/gin" "github.com/liangdas/mqant/log" ) func GetSignStr(send interface{}, pass ...string) string { m := StructToMapJson(send) str := []string{} for i := range m { if i == "sign" { continue } shouldPass := false for _, v := range pass { if v == i { shouldPass = true break } } if shouldPass { continue } str = append(str, i) } sort.Strings(str) signStr := "" for i, v := range str { signStr += fmt.Sprintf("%v=%v", v, m[v]) if i != len(str)-1 { signStr += "&" } } log.Debug("signStr:%s", signStr) return signStr } // 包含空字段 func GetSignStrEmpty(send interface{}, pass ...string) string { m := StructToMapJsonEmpty(send) str := []string{} for i := range m { if i == "sign" { continue } shouldPass := false for _, v := range pass { if v == i { shouldPass = true break } } if shouldPass { continue } str = append(str, i) } sort.Strings(str) signStr := "" for i, v := range str { signStr += fmt.Sprintf("%v=%v", v, m[v]) if i != len(str)-1 { signStr += "&" } } log.Debug("signStr:%s", signStr) return signStr } // 连接参数时不加&符号,且不加key值,直接value拼接 func GetSignStr2(send interface{}, pass ...string) string { m := StructToMapJson(send) str := []string{} for i := range m { if i == "sign" { continue } shouldPass := false for _, v := range pass { if v == i { shouldPass = true break } } if shouldPass { continue } str = append(str, i) } sort.Strings(str) signStr := "" for _, v := range str { signStr += fmt.Sprintf("%v", m[v]) } log.Debug("signStr:%s", signStr) return signStr } func StructToMapJson(obj interface{}) map[string]interface{} { t := reflect.TypeOf(obj) v := reflect.ValueOf(obj) if t.Kind() == reflect.Ptr { t = t.Elem() v = v.Elem() } var result = make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { if v.Field(i).Kind() == reflect.Ptr && v.Field(i).IsNil() { continue } tagName := t.Field(i).Tag.Get("json") if tagName != "" && tagName != "-" && !v.Field(i).IsZero() { data := v.Field(i).Interface() if v.Field(i).Kind() == reflect.Struct { data = GetSignStr(data) } name := strings.Split(tagName, ",") result[name[0]] = data } } return result } func StructToMapJsonEmpty(obj interface{}) map[string]interface{} { t := reflect.TypeOf(obj) v := reflect.ValueOf(obj) if t.Kind() == reflect.Ptr { t = t.Elem() v = v.Elem() } var result = make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { if v.Field(i).Kind() == reflect.Ptr && v.Field(i).IsNil() { continue } tagName := t.Field(i).Tag.Get("json") if tagName != "" && tagName != "-" { data := v.Field(i).Interface() if v.Field(i).Kind() == reflect.Struct { data = GetSignStr(data) } name := strings.Split(tagName, ",") result[name[0]] = data } } return result } // 根据body里的字段直接拼接出签名字符串(去除null) func GetSignStrNull(str string, pass ...string) string { m := map[string]json.RawMessage{} sortStrs := []string{} json.Unmarshal([]byte(str), &m) for i := range m { sortStrs = append(sortStrs, i) } signStr := "" sort.Strings(sortStrs) for _, v := range sortStrs { shouldPass := false for _, s := range pass { if v == s { shouldPass = true break } } if shouldPass { continue } if len(m[v]) > 1 && m[v][0] == 34 { m[v] = m[v][1 : len(m[v])-1] } if len(m[v]) == 0 || string(m[v]) == "null" { continue } signStr += fmt.Sprintf("%v=%v", v, string(m[v])) signStr += "&" } signStr = signStr[:len(signStr)-1] log.Debug("signStr:%v", signStr) return signStr } func SHA512(data string) string { hash := sha512.Sum512([]byte(data)) return fmt.Sprintf("%x", hash) } func GetSignStrGet(vals url.Values, pass ...string) string { sortStrs := []string{} for k := range vals { sortStrs = append(sortStrs, k) } signStr := "" sort.Strings(sortStrs) for _, v := range sortStrs { shouldPass := false for _, s := range pass { if v == s { shouldPass = true break } } if shouldPass { continue } if len(vals.Get(v)) == 0 { continue } signStr += fmt.Sprintf("%v=%v", v, vals.Get(v)) signStr += "&" } signStr = signStr[:len(signStr)-1] log.Debug("signStr:%v", signStr) return signStr } func GetSignStrFormURLEncode(c *gin.Context, model interface{}, pass ...string) string { sortStrs := []string{} for k := range c.Request.URL.Query() { sortStrs = append(sortStrs, k) } // ref := reflect.ValueOf(model) reft := reflect.TypeOf(model) if reft.Kind() == reflect.Ptr { // ref = ref.Elem() reft = reft.Elem() } signStr := "" sort.Strings(sortStrs) for _, v := range sortStrs { shouldPass := false for _, s := range pass { if v == s { shouldPass = true break } } if shouldPass { continue } param := c.Query(v) if len(param) == 0 { continue } first := v[0] tmpName := strings.ToUpper(string(first)) + v[1:] field, ok := reft.FieldByName(tmpName) if ok && field.Tag.Get("encode") == "1" { // 需要urlencode param, _ = url.QueryUnescape(param) } signStr += fmt.Sprintf("%v=%v", v, param) signStr += "&" } fmt.Println(signStr) signStr = signStr[:len(signStr)-1] log.Debug("signStr:%v", signStr) return signStr } // 根据body里的字段直接拼接出签名字符串 func GetSignStrURLEncode(str string, pass ...string) string { sortStrs := []string{} all, err := url.ParseQuery(str) if err != nil { log.Error("err:%e", err) return "" } for k := range all { sortStrs = append(sortStrs, k) } signStr := "" sort.Strings(sortStrs) for _, v := range sortStrs { shouldPass := false for _, s := range pass { if v == s { shouldPass = true break } } if shouldPass { continue } tmp := all.Get(v) if len(tmp) > 1 && tmp[0] == 34 { tmp = tmp[1 : len(tmp)-1] } if len(tmp) == 0 { continue } signStr += fmt.Sprintf("%v=%v", v, string(tmp)) signStr += "&" } signStr = signStr[:len(signStr)-1] log.Debug("signStr:%v", signStr) return signStr }