2023-08-02 03:13:28 +00:00
|
|
|
package hash
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2023-08-08 02:53:28 +00:00
|
|
|
"reflect"
|
2023-08-02 03:13:28 +00:00
|
|
|
"sort"
|
|
|
|
)
|
|
|
|
|
|
|
|
func JsonHashKey(v interface{}) string {
|
2023-08-08 02:53:28 +00:00
|
|
|
|
|
|
|
if reflect.TypeOf(v).Kind() == reflect.String {
|
|
|
|
var obj interface{}
|
|
|
|
err := json.Unmarshal([]byte(v.(string)), &obj)
|
|
|
|
if err == nil {
|
|
|
|
// 反序列化成功,直接替换v
|
|
|
|
v = obj
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-02 03:13:28 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|