Golang中实现数据脱敏处理的go-mask包分享

作者:Go学堂 时间:2024-02-12 17:24:55 

今天给大家推荐一款在输出中对敏感数据进行脱敏的工作包:go-mask。

那么,什么是对敏感数据脱敏呢?就是将敏感信息输出的时候替换成星号或其他字符。比如手机号码,身份证信息,姓名等。

go-mask包还是比较新的,是在两周前提交的。所以星标只有71个。星标虽少,但功能还是很强大的。我们看看go-mask都有哪些功能。

特征

  • 通过结构体的tag功能可以脱敏结构体中的任何字段

  • 除了使用go-mask的内置的脱敏函数外,用户还可以自定义脱敏函数。

支持的tags标签

go-mask只提供了有限的几个tags。原因是用户可以根据需要自定义脱敏函数。以下是go-mask支持的tags:

tagtype描述
mask:"filled"string输出和原字符串相同个数的脱敏字符。例如:原字符串是4个字符,那么就输出4个星号:****
mask:"filledXXX"stringXXX是脱敏字符的个数。即输出XXX个脱敏字符。例如:mask:"filled3"代表最终输出"***"
mask:"fixed"string输出固定个数的脱敏字符,默认是8个字符。例如:********
mask:"hash"string对原字符串使用sha1哈希输出
mask:"randomXXX"int / float64XXX代表数字值。将原值转换成0-XXX之间的随机值输出
mask:"zero"any输出对应类型的零值

如何使用

对字符串类型脱敏

package main
import (
"fmt"
mask "github.com/showa-93/go-mask"
)
func main() {
maskValue, _ := mask.String(mask.MaskTypeFixed, "Hello World!!")
fmt.Println(maskValue) //输出固定的8个脱敏字符: ********
}

对结构体中的string类型字段进行脱敏处理。如下:

package main
import (
"fmt"
mask "github.com/showa-93/go-mask"
)
func main() {
value := struct {
Title string   `mask:"filled"`
Casts []string `mask:"fixed"`
}{
Title: "Catch Me If You Can",
Casts: []string{
"Thomas Jeffrey \"Tom\" Hanks",
"Leonardo Wilhelm DiCaprio",
},
}
   maskValue, _ := mask.Mask(value)
fmt.Printf("value:%+v\n", value)
fmt.Printf("maskValue:%+v\n", maskValue) //脱敏字符输出符号是:*
   masker := mask.NewMasker()
masker.SetMaskChar("-") //自定义脱敏字符为 -
   // 给对应的tag注册对应的脱敏处理函数
masker.RegisterMaskStringFunc(mask.MaskTypeFilled, masker.MaskFilledString)
masker.RegisterMaskStringFunc(mask.MaskTypeFixed, masker.MaskFixedString)
maskValue2, _ := masker.Mask(value)
fmt.Printf("maskValue2:%+v\n", maskValue2)
}

输出结果如下:

value:{Title:Catch Me If You Can Casts:[Thomas Jeffrey "Tom" Hanks Leonardo Wilhelm DiCaprio]}
maskValue:{Title:******************* Casts:[******** ********]}
maskValue2:{Title:------------------- Casts:[-------- --------]}

对int/float64类型字段脱敏

对int/float64类型的字段一般使用mask:"randomXXX"的标签,表示转换成从0到XXX的随机数。如下:

package main
import (
"fmt"
mask "github.com/showa-93/go-mask"
)
func main() {
{
maskValue, _ := mask.Int("random100", 10)
fmt.Println(maskValue)
}
{
maskValue, _ := mask.Float64("random100.2", 12.3)
fmt.Println(maskValue)
}
{
value := struct {
Price   int     `mask:"random1000"`
Percent float64 `mask:"random1.3"`
}{
Price:   300,
Percent: 0.80,
}
masker := mask.NewMasker()
masker.RegisterMaskIntFunc(mask.MaskTypeRandom, masker.MaskRandomInt)
masker.RegisterMaskFloat64Func(mask.MaskTypeRandom, masker.MaskRandomFloat64)
maskValue, _ := mask.Mask(value)
maskValue2, _ := masker.Mask(value)
fmt.Printf("%+v\n", maskValue)
fmt.Printf("%+v\n", maskValue2)
}
}

对应的输出结果如下:

29
50.45
{Price:917 Percent:0.183}
{Price:733 Percent:0.241}

对slice类型脱敏处理

对slice类型的处理本质上还是对基础类型的处理,类似于结构体或对应的string/int/float64类型。如下:

package main
import (
"fmt"
"github.com/showa-93/go-mask"
)
type Value struct {
Name string `mask:"filled"`
Type int    `mask:"random10"`
}
func main() {
values := []Value{
{
Name: "Thomas Jeffrey \"Tom\" Hanks",
Type: 1,
},
{
Name: "Leonardo Wilhelm DiCaprio",
Type: 2,
},
}
masker := mask.NewMasker()
masker.SetMaskChar("+")
masker.RegisterMaskStringFunc(mask.MaskTypeFilled, masker.MaskFilledString)
masker.RegisterMaskIntFunc(mask.MaskTypeRandom, masker.MaskRandomInt)
maskValues, _ := mask.Mask(values)
maskValues2, _ := masker.Mask(values)
fmt.Printf("%+v\n", values)
fmt.Printf("%+v\n", maskValues)
fmt.Printf("%+v\n", maskValues2)
}

输出如下:

[{Name:Thomas Jeffrey "Tom" Hanks Type:1} {Name:Leonardo Wilhelm DiCaprio Type:2}]
[{Name:************************** Type:8} {Name:************************* Type:9}]
[{Name:++++++++++++++++++++++++++ Type:4} {Name:+++++++++++++++++++++++++ Type:8}]

对map类型进行处理

对map类型的处理,是处理的map中的value,对key不做处理。如下:

package main
import (
"fmt"
"github.com/showa-93/go-mask"
)
type Value struct {
Name string `mask:"filled"`
Type int    `mask:"random10"`
}
func main() {
values := map[string]Value{
"one": {
Name: "Thomas Jeffrey \"Tom\" Hanks",
Type: 1,
},
"two": {
Name: "Leonardo Wilhelm DiCaprio",
Type: 2,
},
}
masker := mask.NewMasker()
masker.SetMaskChar("")
masker.RegisterMaskStringFunc(mask.MaskTypeFilled, masker.MaskFilledString)
masker.RegisterMaskIntFunc(mask.MaskTypeRandom, masker.MaskRandomInt)
maskValues, _ := mask.Mask(values)
maskValues2, _ := masker.Mask(values)
fmt.Printf("%+v\n", values)
fmt.Printf("%+v\n", maskValues)
fmt.Printf("%+v\n", maskValues2)
}

输出结果如下:

map[one:{Name:Thomas Jeffrey "Tom" Hanks Type:1} two:{Name:Leonardo Wilhelm DiCaprio Type:2}]
map[one:{Name:************************** Type:8} two:{Name:************************* Type:6}]
map[one:{Name: Type:6} two:{Name: Type:2}]

自定义脱敏函数

go-mask包还支持自定义的脱敏函数的处理。将定义好的函数通过mask.RegisterMaskStringFunc函数进行注册即可。如下,定义了regexp标签和MaskRegExp脱敏处理函数:

package main
import (
"fmt"
"regexp"
"strings"
mask "github.com/showa-93/go-mask"
)
func init() {
maskTypeRegExp := "regexp"
mask.RegisterMaskStringFunc(maskTypeRegExp, MaskRegExp)
}
// MaskRegExp is sample to add a custom mask function
func MaskRegExp(arg, value string) (string, error) {
var (
reg *regexp.Regexp
err error
)
reg, err = regexp.Compile(arg)
if err != nil {
return "", err
}
indexes := reg.FindStringSubmatchIndex(value)
if len(indexes) >= 4 && indexes[2] >= 0 && indexes[3] >= 0 {
var sb strings.Builder
sb.WriteString(value[:indexes[2]])
sb.WriteString(mask.MaskChar())
sb.WriteString(value[indexes[3]:])
return sb.String(), nil
}
return value, nil
}
func main() {
mask.SetMaskChar("cat")
type Hachiware struct {
Message string `mask:"regexp(gopher)."`
}
input := Hachiware{Message: "I love gopher!"}
got, _ := mask.Mask(input)
fmt.Printf("%+v\n", input)
fmt.Printf("%+v\n", got)
// The Masker initialized with NewMasker does not have
// any custom masking functions registered, so no masking will occur
masker := mask.NewMasker()
got2, _ := masker.Mask(input)
fmt.Printf("%+v\n", got2)
}

输出结果:

{Message:I love gopher!}
{Message:I love cat!}
{Message:I love gopher!}

来源:https://juejin.cn/post/7227729079479599141

标签:Go,go-mask,数据脱敏
0
投稿

猜你喜欢

  • JavaScript错误处理try..catch...finally+涵盖throw+TypeError+RangeError

    2024-04-22 13:26:05
  • scrapy利用selenium爬取豆瓣阅读的全步骤

    2022-09-24 01:28:15
  • asp如何让服务器延时执行更改后的数据?

    2010-05-13 16:35:00
  • Python 权限控制模块 Casbin

    2022-09-21 07:35:46
  • 超详细的sql2005图解安装全过程第1/2页

    2024-01-24 17:11:55
  • scrollWidth,clientWidth与offsetWidth的区别

    2024-04-22 22:28:38
  • Python如何对文件进行重命名

    2022-01-20 12:31:51
  • 向数据库中插入数据并返回当前插入的行数及全局变量@@IDENTITY应用

    2024-01-13 05:11:00
  • asp日期时间格式化函数

    2009-12-14 12:56:00
  • Python实现拷贝多个文件到同一目录的方法

    2021-09-03 20:56:25
  • Python中的sort()方法使用基础教程

    2022-03-07 21:44:09
  • python中前缀运算符 *和 **的用法示例详解

    2022-05-19 08:41:31
  • Tensorflow卷积实现原理+手写python代码实现卷积教程

    2021-12-21 20:12:52
  • python协程之动态添加任务的方法

    2021-03-24 04:27:54
  • Python制作数据导入导出工具

    2023-07-25 06:59:59
  • PHP基于phpqrcode类生成二维码的方法示例详解

    2023-07-15 22:57:52
  • Python实现对象转换为xml的方法示例

    2022-12-18 01:39:18
  • golang copy函数使用的坑

    2023-07-09 19:53:44
  • c#编写的高并发数据库控制访问代码

    2024-01-16 04:57:04
  • Python脚本实现网卡流量监控

    2022-11-27 11:36:51
  • asp之家 网络编程 m.aspxhome.com