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

Commit

Permalink
支持一键输出常用格式
Browse files Browse the repository at this point in the history
支持解析基础 adblock 规则
  • Loading branch information
CalmLong committed Mar 22, 2020
1 parent c331f56 commit 778abbf
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 24 deletions.
58 changes: 42 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@

## 应用场景

例如将 `dnsmasq-list` 中的域名去掉前缀 `server=/` 以及后缀 `/114.114.114.114` 或者替换为其他的内容
将现有域名格式化为目标工具所支持的格式

**通常需要解析标准或者非标准的 `hosts` 域名列表才应是使用本工具的主要原因**

例如将 [dnsmasq-list](https://github.com/felixonmars/dnsmasq-china-list/blob/master/accelerated-domains.china.conf) 中的域名去掉前缀 `server=/` 以及后缀 `/114.114.114.114`
或者替换为你想要的内容亦或者仅输出纯粹的域名

## 功能

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

## 支持格式

可被解析的域名格式:

* hosts(标准或者非标准)
* dnsmasq
* adblock(基础)

输出的格式:

可以输出任意格式的域名

> 只能为域名前后添加任意字符,不支持域名内添加字符;
> 例如 `github.com` 不能被输出为 `git*hub.com`
## 参数

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

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

`-p` 前两(0,1)个参数为子域名的前/后缀,后两个(2,3)为主域名的前后缀,
四个参数均为必填,不需要添加内容则用 `""` 代替
* hosts
* dnsmasq
* v2ray
* adblock
* only(仅输出域名)

`-e` 修改 `-v` 参数输出的默认值,仅支持 `dnsmasq``hosts`

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

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

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

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

* 替换为 AdGuardHome 支持的格式:
* 输出 V2Ray 支持的格式:

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

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

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

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

* 仅输出域名

`./domain-parse -c=url.txt -p="","","",""`
`./domain-parse -c=url.txt -v only`

## 输出

Expand Down
86 changes: 78 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"crypto/tls"
"flag"
"fmt"
"io"
"log"
"net"
Expand Down Expand Up @@ -35,6 +36,7 @@ var localList = []string{
func GetList(list []string) []io.Reader {
bodys := make([]io.Reader, 0)
for _, l := range list {
log.Println("getting", l)
resp, err := req.Get(l)
if err != nil {
panic(err)
Expand Down Expand Up @@ -102,7 +104,15 @@ func Parase(list map[string]struct{}, writer *bufio.Writer, params []string) {
}
}

func deleteStr(newOrg string, strs []string) string {
for _, s := range strs {
newOrg = strings.ReplaceAll(newOrg, s, "")
}
return newOrg
}

func Resolve(bodys []io.Reader, list map[string]struct{}) {
const j = '#'
for _, body := range bodys {
reader := bufio.NewReader(body)
for {
Expand All @@ -111,15 +121,15 @@ func Resolve(bodys []io.Reader, list map[string]struct{}) {
break
}
original := string(o)
// 第一个字符为 # 时跳过
if strings.IndexRune(original, '#') == 0 {
// 第一个字符为 # 或 ! 时跳过
if strings.IndexRune(original, j) == 0 || strings.IndexRune(original, '!') == 0 {
continue
}
// 为空行时跳过
if strings.TrimSpace(original) == "" {
continue
}
// 用于 https://hosts-file.net/ad_servers.txt
// 用于 https://hosts-file.net/ad_servers.txt 等中间包含特殊空格的
if strings.ContainsRune(original, '\t') {
original = strings.ReplaceAll(original, "\t", " ")
}
Expand All @@ -132,18 +142,30 @@ func Resolve(bodys []io.Reader, list map[string]struct{}) {
// 移除行中的空格
newOrg = strings.TrimSpace(newOrg)
// 再一次验证第一个字符为 # 时跳过
if strings.IndexRune(original, '#') == 0 {
if strings.IndexRune(original, j) == 0 {
continue
}
if strings.ContainsRune(newOrg, '#') {
newOrg = newOrg[:strings.IndexRune(newOrg, '#')]
if strings.ContainsRune(newOrg, j) {
newOrg = newOrg[:strings.IndexRune(newOrg, j)]
}
// dnsmasq-list
newOrg = strings.ReplaceAll(newOrg, "server=/", "")
newOrg = strings.ReplaceAll(newOrg, "/114.114.114.114", "")
newOrg = deleteStr(newOrg, []string{"server=/", "/114.114.114.114"})
if !formatter(newOrg) {
continue
}
// adblock
if strings.ContainsRune(newOrg, '^') {
// 子域名包含 * 的不会被解析
if strings.ContainsRune(newOrg, '*') {
continue
}
// 表达式不会被解析
if strings.Contains(newOrg, "/^") {
continue
}
// 基础白名单规则会被一同解析
newOrg = deleteStr(newOrg, []string{"||", "^", "@@"})
}
newOrg = strings.TrimSpace(newOrg)
// 检测是否有端口号,有则移除端口号
if strings.ContainsRune(newOrg, ':') {
Expand Down Expand Up @@ -191,8 +213,49 @@ func transport() *http.Transport {
}
}

var vals = []string{
dnsmasq, v2ray, hosts, adblock, only,
}

const (
dnsmasq = "dnsmasq"
v2ray = "v2ray"
hosts = "hosts"
adblock = "adblock"
only = "only"
)

func domainFormat(value, exp string) []string {
vals := make([]string, 0)
switch value {
case dnsmasq:
v := "/114.114.114.114"
if exp != "" {
v = "/" + exp
}
vals = append(vals, "server=/", v, "server=/", v)
case v2ray:
vals = append(vals, "full:", "", "domain:", "")
case adblock:
vals = append(vals, "||", "^", "||", "^")
case hosts:
v := "0.0.0.0 "
if exp != "" {
v = exp + " "
}
vals = append(vals, v, "", v, "")
case only:
vals = append(vals, "", "", "", "")
default:
panic(fmt.Sprintln(value, " is an unsupported format"))
}
return vals
}

func main() {
file := flag.String("c", "", "")
val := flag.String("v", "", "")
exp := flag.String("e", "", "")
pars := flag.String("p", "", "")
flag.Parse()
params = make([]string, 0)
Expand All @@ -202,6 +265,13 @@ func main() {
log.Println(err)
return
}
if strings.TrimSpace(*val) != "" {
for _, v := range vals {
if v == *val {
params = domainFormat(v, strings.TrimSpace(*exp))
}
}
}
body := bufio.NewReader(f)
domainList := make([]string, 0)
for {
Expand Down

0 comments on commit 778abbf

Please sign in to comment.