代码拉取完成,页面将自动刷新
package util
import (
"fmt"
"io"
"log"
"net/http"
"regexp"
"strings"
"time"
)
// 查找字符串中第一个IPV4地址
func MatchIPv4(s string) (string, error) {
reg, err := regexp.Compile(`(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}`)
if err != nil {
return "", err
}
ip := reg.FindString(strings.TrimSpace(s))
if ip == "" {
return "", fmt.Errorf("not match ipv4 address")
}
return ip, nil
}
// 查找字符串中第一个IPV6地址
func MatchIPv6(s string) (string, error) {
reg, err := regexp.Compile(`(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?`)
if err != nil {
return "", err
}
ip := reg.FindString(strings.TrimSpace(s))
if ip == "" {
return "", fmt.Errorf("not match ipv6 address")
}
return ip, nil
}
// 获取ipv4地址接口
var ipv4Apis = []string{"http://ipv4.ddnspod.com", "http://ipv4.testipv6.cn/ip/", "http://ipv4.icanhazip.com/", "https://api4.ipify.org/", "https://ip4.seeip.org/", "http://api-ipv4.ip.sb/ip", "http://v4.ipv6-test.com/api/myip.php"}
// 获取ipv6地址接口
var ipv6Apis = []string{"http://ipv6.ddnspod.com", "http://ipv6.testipv6.cn/ip/", "http://ipv6.icanhazip.com/", "https://api6.ipify.org/", "https://ip6.seeip.org/", "http://api-ipv6.ip.sb/ip", "http://v6.ipv6-test.com/api/myip.php"}
func request(url string) (string, error) {
client := &http.Client{Transport: CustomDnsWithNoProxyHttpTransport, Timeout: 3 * time.Second}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", err
}
res, err := client.Do(req)
if err != nil {
return "", err
}
defer res.Body.Close()
if !(res.StatusCode >= 200 && res.StatusCode < 300) {
return "", fmt.Errorf("error status code: %d", res.StatusCode)
}
body, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
return string(body), nil
}
// 获取当前上网的公网ip地址
//
// @param ipType: V4 或 V6
func GetPublicIP(ipType string) (string, error) {
var apis []string
var matchFn func(s string) (string, error)
if ipType == "V6" {
apis = ipv6Apis
matchFn = MatchIPv6
} else if ipType == "V4" {
apis = ipv4Apis
matchFn = MatchIPv4
} else {
return "", fmt.Errorf("error ipType: %s", ipType)
}
res := make(chan string, len(apis))
for _, v := range apis {
go func(url string) {
body, err := request(url)
if err != nil {
log.Println(err)
res <- ""
return
}
ip, err := matchFn(body)
if err != nil {
log.Println(err)
res <- ""
return
}
res <- ip
}(v)
}
ips := map[string]int{}
successCount := 0
for range apis {
v := <-res
if v == "" {
continue
}
c := ips[v]
ips[v] = c + 1
successCount += 1
}
for k, v := range ips {
if v >= successCount/2 {
return k, nil
}
}
return "", fmt.Errorf("not found ip%s address", ipType)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。