package hash import ( "bytes" "crypto/sha256" "encoding/json" "fmt" "sort" ) func JsonHashKey(v interface{}) string { if _, ok := v.(string); ok { var obj interface{} err := json.Unmarshal([]byte(v.(string)), &obj) if err == nil { // 反序列化成功,直接替换v v = obj } } h := sha256.New() h.Write(marshalOrdered(v)) return fmt.Sprintf("%x", h.Sum(nil)) } func marshalOrdered(v interface{}) []byte { switch v := v.(type) { case map[string]interface{}: sortedKeys := make([]string, 0, len(v)) for key := range v { sortedKeys = append(sortedKeys, key) } sort.Strings(sortedKeys) var buf bytes.Buffer buf.WriteByte('{') for i, key := range sortedKeys { if i > 0 { buf.WriteByte(',') } b, err := json.Marshal(key) if err != nil { panic(err) } buf.Write(b) buf.WriteByte(':') b = marshalOrdered(v[key]) buf.Write(b) } buf.WriteByte('}') return buf.Bytes() case []interface{}: var buf bytes.Buffer sort.Slice(v, func(i, j int) bool { return bytes.Compare(marshalOrdered(v[i]), marshalOrdered(v[j])) == 1 }) buf.WriteByte('[') for i, val := range v { if i > 0 { buf.WriteByte(',') } b := marshalOrdered(val) buf.Write(b) } buf.WriteByte(']') return buf.Bytes() default: b, err := json.Marshal(v) if err != nil { panic(err) } return b } }