-
Notifications
You must be signed in to change notification settings - Fork 42
/
auto.go
143 lines (132 loc) · 3.13 KB
/
auto.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package codec
import (
"bytes"
"encoding/binary"
"github.com/asaskevich/govalidator"
"net/url"
"regexp"
"strconv"
"strings"
)
type AutoDecodeResult struct {
Type string
TypeVerbose string
Origin string
Result string
}
var _jsonUnicodeEncoding = regexp.MustCompile(`(?i)\\u[\dabcdef]{4}`)
var base64Regexp = regexp.MustCompile(`(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})`)
func AutoDecode(i interface{}) []*AutoDecodeResult {
rawBytes := interfaceToBytes(i)
rawStr := string(rawBytes)
var results []*AutoDecodeResult
var origin = rawStr
for i := 0; i < 100; i++ {
if r, _ := regexp.MatchString(`%[\da-fA-F]{2}`, rawStr); r {
rawStr, _ = url.QueryUnescape(rawStr)
if rawStr != "" {
results = append(results, &AutoDecodeResult{
Type: "UrlDecode",
TypeVerbose: "URL解码",
Origin: origin,
Result: rawStr,
})
origin = rawStr
continue
}
}
if r := _jsonUnicodeEncoding.MatchString(rawStr); r {
rawStr = _jsonUnicodeEncoding.ReplaceAllStringFunc(rawStr, func(s string) string {
number, err := DecodeHex(strings.TrimLeft(s, "\\u"))
if err != nil {
return s
}
return string(rune(binary.BigEndian.Uint16(number)))
})
if rawStr != "" {
results = append(results, &AutoDecodeResult{
Type: "Json Unicode Decode",
TypeVerbose: "Json Unicode 解码",
Origin: origin,
Result: rawStr,
})
origin = rawStr
continue
}
}
if govalidator.IsBase64(rawStr) {
// 解码解到 BASE64
rawStr = base64Regexp.ReplaceAllStringFunc(rawStr, func(s string) string {
result, err := DecodeBase64(s)
if err != nil {
return s
}
for _, ch := range []rune(string(result)) {
if !strconv.IsPrint(ch) {
return s
}
}
return EscapeInvalidUTF8Byte(result)
})
if rawStr != "" && rawStr != origin {
results = append(results, &AutoDecodeResult{
Type: "Base64 Decode",
TypeVerbose: "Base64 解码",
Origin: origin,
Result: rawStr,
})
origin = rawStr
continue
}
}
// base64
if strings.Count(rawStr, ".") > 1 {
var blocks = strings.Split(rawStr, ".")
var buf bytes.Buffer
var failed = false
for index, i := range blocks {
base64Decoded, _ := DecodeBase64(i)
if len(base64Decoded) <= 0 {
failed = true
break
}
if govalidator.IsPrintableASCII(string(base64Decoded)) {
buf.WriteString(EscapeInvalidUTF8Byte(base64Decoded))
} else {
buf.WriteString(i)
}
if index != len(blocks)-1 {
buf.WriteByte('.')
}
}
if failed {
continue
}
rawStr = buf.String()
if rawStr != "" && rawStr != origin {
results = append(results, &AutoDecodeResult{
Type: "jwt",
TypeVerbose: "JWT",
Origin: origin,
Result: rawStr,
})
origin = rawStr
continue
}
}
if rawStr == origin {
break
}
}
if len(results) <= 0 {
return []*AutoDecodeResult{
{
Type: "No",
TypeVerbose: "无编码",
Origin: rawStr,
Result: rawStr,
},
}
}
return results
}