sensitive.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package service
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/anknown/ahocorasick"
  6. "one-api/constant"
  7. "strings"
  8. )
  9. // SensitiveWordContains 是否包含敏感词,返回是否包含敏感词和敏感词列表
  10. func SensitiveWordContains(text string) (bool, []string) {
  11. // 构建一个AC自动机
  12. m := initAc()
  13. hits := m.MultiPatternSearch([]rune(text), false)
  14. if len(hits) > 0 {
  15. words := make([]string, 0)
  16. for _, hit := range hits {
  17. words = append(words, string(hit.Word))
  18. }
  19. return true, words
  20. }
  21. return false, nil
  22. }
  23. // SensitiveWordReplace 敏感词替换,返回是否包含敏感词和替换后的文本
  24. func SensitiveWordReplace(text string, returnImmediately bool) (bool, []string, string) {
  25. text = strings.ToLower(text)
  26. m := initAc()
  27. hits := m.MultiPatternSearch([]rune(text), returnImmediately)
  28. if len(hits) > 0 {
  29. words := make([]string, 0)
  30. for _, hit := range hits {
  31. pos := hit.Pos
  32. word := string(hit.Word)
  33. text = text[:pos] + " *###* " + text[pos+len(word):]
  34. words = append(words, word)
  35. }
  36. return true, words, text
  37. }
  38. return false, nil, text
  39. }
  40. func initAc() *goahocorasick.Machine {
  41. m := new(goahocorasick.Machine)
  42. dict := readRunes()
  43. if err := m.Build(dict); err != nil {
  44. fmt.Println(err)
  45. return nil
  46. }
  47. return m
  48. }
  49. func readRunes() [][]rune {
  50. var dict [][]rune
  51. for _, word := range constant.SensitiveWords {
  52. word = strings.ToLower(word)
  53. l := bytes.TrimSpace([]byte(word))
  54. dict = append(dict, bytes.Runes(l))
  55. }
  56. return dict
  57. }