78 lines
2.0 KiB
Go
78 lines
2.0 KiB
Go
|
package sensitive
|
|||
|
|
|||
|
import (
|
|||
|
"reflect"
|
|||
|
"strings"
|
|||
|
)
|
|||
|
|
|||
|
// Desensitization
|
|||
|
// @description: 脱敏
|
|||
|
// @param r any: 要脱敏的数据(只支持结构体)
|
|||
|
// @param skip bool: 是否跳过脱敏
|
|||
|
// @return err error: 错误信息
|
|||
|
func Desensitization(r any, skip bool) (err error) {
|
|||
|
// 处理Data的值,如果也是结构体,就处理每个字段的标签,如果包含sen,就把sen改为sen_id
|
|||
|
if r == nil || skip {
|
|||
|
return
|
|||
|
}
|
|||
|
// 判断是不是结构体
|
|||
|
isPointer := reflect.TypeOf(r).Kind() == reflect.Ptr
|
|||
|
dataType := reflect.TypeOf(r).Kind()
|
|||
|
if isPointer {
|
|||
|
dataType = reflect.TypeOf(r).Elem().Kind()
|
|||
|
}
|
|||
|
//log.Printf("数据类型: %v,是否为指针: %v", dataType, isPointer)
|
|||
|
|
|||
|
// 处理是数组的情况
|
|||
|
if dataType == reflect.Slice || dataType == reflect.Array {
|
|||
|
//log.Println("传入类型为数组")
|
|||
|
rs := reflect.ValueOf(r)
|
|||
|
if isPointer {
|
|||
|
rs = rs.Elem()
|
|||
|
}
|
|||
|
for i := 0; i < rs.Len(); i++ {
|
|||
|
id := rs.Index(i)
|
|||
|
err = Desensitization(id.Addr().Interface(), skip)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 如果是指针结构体,处理脱敏
|
|||
|
if dataType == reflect.Struct {
|
|||
|
val := reflect.ValueOf(r)
|
|||
|
if isPointer {
|
|||
|
val = val.Elem()
|
|||
|
}
|
|||
|
|
|||
|
for i := 0; i < val.NumField(); i++ {
|
|||
|
f := val.Field(i)
|
|||
|
tag := val.Type().Field(i).Tag.Get("sen")
|
|||
|
|
|||
|
//log.Printf("类型: %v -> %v 值: %v 脱敏标签是否存在: %v", f.Type(), f.Kind(), f.Interface(), tag != "")
|
|||
|
// 如果是结构体,递归调用
|
|||
|
if f.Kind() == reflect.Interface {
|
|||
|
//log.Println("开始处理子级")
|
|||
|
err = Desensitization(f.Interface(), skip)
|
|||
|
}
|
|||
|
|
|||
|
if tag != "" {
|
|||
|
// 脱敏标签存在,处理一下,取出规则Id和占位符
|
|||
|
ruleId := strings.Split(tag, ",")[0]
|
|||
|
placeholder := strings.Split(tag, ",")[1]
|
|||
|
//log.Printf("脱敏规则Id: %v, 占位符: %v", ruleId, placeholder)
|
|||
|
|
|||
|
// 处理脱敏
|
|||
|
if handle, ok := senRuleMap[ruleId]; ok {
|
|||
|
newData := handle(f.Interface().(string), placeholder)
|
|||
|
//log.Printf("脱敏后的值: %v", newData)
|
|||
|
f.SetString(newData)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return
|
|||
|
}
|