Skip to content
This repository was archived by the owner on Mar 8, 2021. It is now read-only.

Commit 778abbf

Browse files
committed
支持一键输出常用格式
支持解析基础 adblock 规则
1 parent c331f56 commit 778abbf

2 files changed

Lines changed: 120 additions & 24 deletions

File tree

README.md

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
## 应用场景
88

9-
例如将 `dnsmasq-list` 中的域名去掉前缀 `server=/` 以及后缀 `/114.114.114.114` 或者替换为其他的内容
9+
将现有域名格式化为目标工具所支持的格式
10+
11+
**通常需要解析标准或者非标准的 `hosts` 域名列表才应是使用本工具的主要原因**
12+
13+
例如将 [dnsmasq-list](https://github.com/felixonmars/dnsmasq-china-list/blob/master/accelerated-domains.china.conf) 中的域名去掉前缀 `server=/` 以及后缀 `/114.114.114.114`
14+
或者替换为你想要的内容亦或者仅输出纯粹的域名
1015

1116
## 功能
1217

@@ -15,38 +20,59 @@
1520
* 支持自动移除域名列表中的注释(不支持网页)
1621
* 支持识别 `http_proxy` 代理变量
1722

23+
## 支持格式
24+
25+
可被解析的域名格式:
26+
27+
* hosts(标准或者非标准)
28+
* dnsmasq
29+
* adblock(基础)
30+
31+
输出的格式:
32+
33+
可以输出任意格式的域名
34+
35+
> 只能为域名前后添加任意字符,不支持域名内添加字符;
36+
> 例如 `github.com` 不能被输出为 `git*hub.com`
37+
1838
## 参数
1939

20-
* `-c` 指定一个 `.txt` 文本路径,里面应当包含域名列表的 URL,每个一行
40+
`-c` 指定一个 `.txt` 文本路径,里面应当包含域名列表的 URL,每个一行
2141

22-
* `-p` 共四个参数,中间用英文的 `,` 隔开
42+
`-v` 输出常见应用程序所支持的格式
2343

24-
`-p` 前两(0,1)个参数为子域名的前/后缀,后两个(2,3)为主域名的前后缀,
25-
四个参数均为必填,不需要添加内容则用 `""` 代替
44+
* hosts
45+
* dnsmasq
46+
* v2ray
47+
* adblock
48+
* only(仅输出域名)
49+
50+
`-e` 修改 `-v` 参数输出的默认值,仅支持 `dnsmasq``hosts`
2651

27-
## 示例
52+
`-p` 自定义输出域名格式,中间用英文的 `,` 隔开
2853

29-
* 替换为 dnsmasq 支持的格式:
54+
> `-p` 前两(0,1)个参数为子域名的前/后缀,后两个(2,3)为主域名的前后缀,
55+
> 四个参数均为必填,不需要添加内容则用 `""` 代替
3056
31-
`./domain-parse -c=url.txt -p=server=/,/114.114.114.114,server=/,/114.114.114.114`
57+
## 示例
3258

33-
* 替换为 V2Ray 支持的格式:
59+
* 输出自定义格式的域名;通等于 `-v` 中的 `dnsmasq`
3460

35-
`./domain-parse -c=url.txt -p=full:,"",domain:,""`
61+
`./domain-parse -c=url.txt -p=server=/,/114.114.114.114,server=/,/114.114.114.114`
3662

37-
* 替换为 AdGuardHome 支持的格式:
63+
* 输出 V2Ray 支持的格式:
3864

39-
> 由于命令行本身的原因,对于一些特殊的字符你需要使用 "" 括起来表示字符串
65+
`./domain-parse -c=url.txt -v v2ray`
4066

41-
`./domain-parse -c=url.txt -p="||,^,||,^"`
67+
* 指定 `dnsmasq` 解析域名的 IP
4268

43-
* 替换为 hosts 支持的格式:
69+
`./domain-parse -c url.txt -v dnsmasq -e 119.29.29.29`
4470

45-
`./domain-parse -c=url.txt -p="127.0.0.1 ,"",127.0.0.1 ,"""`
71+
输出结果为 `server=/example.com/119.29.29.29`
4672

4773
* 仅输出域名
4874

49-
`./domain-parse -c=url.txt -p="","","",""`
75+
`./domain-parse -c=url.txt -v only`
5076

5177
## 输出
5278

main.go

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bufio"
55
"crypto/tls"
66
"flag"
7+
"fmt"
78
"io"
89
"log"
910
"net"
@@ -35,6 +36,7 @@ var localList = []string{
3536
func GetList(list []string) []io.Reader {
3637
bodys := make([]io.Reader, 0)
3738
for _, l := range list {
39+
log.Println("getting", l)
3840
resp, err := req.Get(l)
3941
if err != nil {
4042
panic(err)
@@ -102,7 +104,15 @@ func Parase(list map[string]struct{}, writer *bufio.Writer, params []string) {
102104
}
103105
}
104106

107+
func deleteStr(newOrg string, strs []string) string {
108+
for _, s := range strs {
109+
newOrg = strings.ReplaceAll(newOrg, s, "")
110+
}
111+
return newOrg
112+
}
113+
105114
func Resolve(bodys []io.Reader, list map[string]struct{}) {
115+
const j = '#'
106116
for _, body := range bodys {
107117
reader := bufio.NewReader(body)
108118
for {
@@ -111,15 +121,15 @@ func Resolve(bodys []io.Reader, list map[string]struct{}) {
111121
break
112122
}
113123
original := string(o)
114-
// 第一个字符为 # 时跳过
115-
if strings.IndexRune(original, '#') == 0 {
124+
// 第一个字符为 # 或 ! 时跳过
125+
if strings.IndexRune(original, j) == 0 || strings.IndexRune(original, '!') == 0 {
116126
continue
117127
}
118128
// 为空行时跳过
119129
if strings.TrimSpace(original) == "" {
120130
continue
121131
}
122-
// 用于 https://hosts-file.net/ad_servers.txt
132+
// 用于 https://hosts-file.net/ad_servers.txt 等中间包含特殊空格的
123133
if strings.ContainsRune(original, '\t') {
124134
original = strings.ReplaceAll(original, "\t", " ")
125135
}
@@ -132,18 +142,30 @@ func Resolve(bodys []io.Reader, list map[string]struct{}) {
132142
// 移除行中的空格
133143
newOrg = strings.TrimSpace(newOrg)
134144
// 再一次验证第一个字符为 # 时跳过
135-
if strings.IndexRune(original, '#') == 0 {
145+
if strings.IndexRune(original, j) == 0 {
136146
continue
137147
}
138-
if strings.ContainsRune(newOrg, '#') {
139-
newOrg = newOrg[:strings.IndexRune(newOrg, '#')]
148+
if strings.ContainsRune(newOrg, j) {
149+
newOrg = newOrg[:strings.IndexRune(newOrg, j)]
140150
}
141151
// dnsmasq-list
142-
newOrg = strings.ReplaceAll(newOrg, "server=/", "")
143-
newOrg = strings.ReplaceAll(newOrg, "/114.114.114.114", "")
152+
newOrg = deleteStr(newOrg, []string{"server=/", "/114.114.114.114"})
144153
if !formatter(newOrg) {
145154
continue
146155
}
156+
// adblock
157+
if strings.ContainsRune(newOrg, '^') {
158+
// 子域名包含 * 的不会被解析
159+
if strings.ContainsRune(newOrg, '*') {
160+
continue
161+
}
162+
// 表达式不会被解析
163+
if strings.Contains(newOrg, "/^") {
164+
continue
165+
}
166+
// 基础白名单规则会被一同解析
167+
newOrg = deleteStr(newOrg, []string{"||", "^", "@@"})
168+
}
147169
newOrg = strings.TrimSpace(newOrg)
148170
// 检测是否有端口号,有则移除端口号
149171
if strings.ContainsRune(newOrg, ':') {
@@ -191,8 +213,49 @@ func transport() *http.Transport {
191213
}
192214
}
193215

216+
var vals = []string{
217+
dnsmasq, v2ray, hosts, adblock, only,
218+
}
219+
220+
const (
221+
dnsmasq = "dnsmasq"
222+
v2ray = "v2ray"
223+
hosts = "hosts"
224+
adblock = "adblock"
225+
only = "only"
226+
)
227+
228+
func domainFormat(value, exp string) []string {
229+
vals := make([]string, 0)
230+
switch value {
231+
case dnsmasq:
232+
v := "/114.114.114.114"
233+
if exp != "" {
234+
v = "/" + exp
235+
}
236+
vals = append(vals, "server=/", v, "server=/", v)
237+
case v2ray:
238+
vals = append(vals, "full:", "", "domain:", "")
239+
case adblock:
240+
vals = append(vals, "||", "^", "||", "^")
241+
case hosts:
242+
v := "0.0.0.0 "
243+
if exp != "" {
244+
v = exp + " "
245+
}
246+
vals = append(vals, v, "", v, "")
247+
case only:
248+
vals = append(vals, "", "", "", "")
249+
default:
250+
panic(fmt.Sprintln(value, " is an unsupported format"))
251+
}
252+
return vals
253+
}
254+
194255
func main() {
195256
file := flag.String("c", "", "")
257+
val := flag.String("v", "", "")
258+
exp := flag.String("e", "", "")
196259
pars := flag.String("p", "", "")
197260
flag.Parse()
198261
params = make([]string, 0)
@@ -202,6 +265,13 @@ func main() {
202265
log.Println(err)
203266
return
204267
}
268+
if strings.TrimSpace(*val) != "" {
269+
for _, v := range vals {
270+
if v == *val {
271+
params = domainFormat(v, strings.TrimSpace(*exp))
272+
}
273+
}
274+
}
205275
body := bufio.NewReader(f)
206276
domainList := make([]string, 0)
207277
for {

0 commit comments

Comments
 (0)