You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
3.5 KiB
Go
160 lines
3.5 KiB
Go
package staros
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io/ioutil"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func splitBy(data, sep string) map[string]string {
|
|
res := make(map[string]string)
|
|
lists := strings.Split(data, "\n")
|
|
for _, v := range lists {
|
|
list := strings.SplitN(v, sep, 2)
|
|
if len(list) != 2 {
|
|
continue
|
|
}
|
|
res[strings.TrimSpace(list[0])] = strings.TrimSpace(list[1])
|
|
}
|
|
return res
|
|
}
|
|
|
|
// 横向替换ASCII<9>
|
|
func ReplaceByte9(data string) string {
|
|
return string(bytes.ReplaceAll([]byte(data), []byte{9}, []byte(" ")))
|
|
}
|
|
|
|
func splitBySpace(data string) []string {
|
|
data = string(bytes.ReplaceAll([]byte(data), []byte{9}, []byte(" ")))
|
|
nomorespace := func(data string) string {
|
|
return strings.ReplaceAll(data, " ", " ")
|
|
}
|
|
for strings.Index(data, " ") >= 0 {
|
|
data = nomorespace(data)
|
|
}
|
|
return strings.Split(data, " ")
|
|
}
|
|
|
|
func readAsString(path string) (string, error) {
|
|
data, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(data), nil
|
|
}
|
|
|
|
func remainOne(data, old, new string) string {
|
|
data = strings.TrimSpace(data)
|
|
if !strings.Contains(data, old) {
|
|
return data
|
|
}
|
|
data = strings.ReplaceAll(data, old, new)
|
|
return remainOne(data, old, new)
|
|
}
|
|
|
|
func parseHexIpPort(str string) (string, int, error) {
|
|
str = strings.TrimSpace(str)
|
|
if len(str) != 13 && len(str) != 37 {
|
|
return "", 0, errors.New("Not a valid ip:port addr:" + str)
|
|
}
|
|
ipPort := strings.Split(str, ":")
|
|
if len(ipPort) != 2 {
|
|
return "", 0, errors.New("Not a valid ip:port addr:" + str)
|
|
}
|
|
if len(ipPort[0]) == 8 {
|
|
ip, err := parseHexIPv4(ipPort[0])
|
|
if err != nil {
|
|
return "", 0, err
|
|
}
|
|
port, err := parseHexPort(ipPort[1])
|
|
return ip, port, err
|
|
}
|
|
|
|
if len(ipPort[0]) == 32 {
|
|
ip, err := parseHexIPv6(ipPort[0])
|
|
if err != nil {
|
|
return "", 0, err
|
|
}
|
|
port, err := parseHexPort(ipPort[1])
|
|
return ip, port, err
|
|
}
|
|
return "", 0, errors.New("Invalid ip address:" + str)
|
|
}
|
|
|
|
func parseHexPort(str string) (int, error) {
|
|
tmpUint32, err := strconv.ParseUint(str, 16, 32)
|
|
return int(tmpUint32), err
|
|
}
|
|
|
|
func parseHexIPv4(str string) (string, error) {
|
|
var result string
|
|
if len(str) != 8 {
|
|
return "", errors.New("Not a vaild ipv4:" + str)
|
|
}
|
|
tmpUint64, err := strconv.ParseUint(str, 16, 32)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
numicIp := uint32(tmpUint64)
|
|
for i := 0; i < 4; i++ {
|
|
result += strconv.FormatUint(uint64(uint8(numicIp>>(8*uint8(i)))), 10) + "."
|
|
}
|
|
return result[0 : len(result)-1], nil
|
|
}
|
|
|
|
func parseHexIPv6(str string) (string, error) {
|
|
var result string
|
|
if len(str) != 32 {
|
|
return "", errors.New("Not a vaild ipv6:" + str)
|
|
}
|
|
for i := 0; i < 4; i++ {
|
|
part := str[i*8 : (i+1)*8]
|
|
tmpUint64, err := strconv.ParseUint(part, 16, 32)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
tmpUint32 := uint32(tmpUint64)
|
|
//07C2022A
|
|
for i := 0; i < 4; i++ {
|
|
tmp := strconv.FormatUint(uint64(uint8(tmpUint32>>uint8(8*i))), 16)
|
|
if len(tmp) == 1 {
|
|
tmp = "0" + tmp
|
|
}
|
|
result += tmp
|
|
if (i+1)%2 == 0 {
|
|
result += ":"
|
|
}
|
|
}
|
|
}
|
|
ipv6 := result[0 : len(result)-1]
|
|
ipv6List := strings.Split(ipv6, ":")
|
|
prepareZero := false
|
|
alreadyZero := false
|
|
for k, v := range ipv6List {
|
|
if v == "0000" && !alreadyZero {
|
|
ipv6List[k] = ""
|
|
prepareZero = true
|
|
continue
|
|
}
|
|
if v != "0000" && prepareZero {
|
|
alreadyZero = true
|
|
}
|
|
var nonZero = 0
|
|
for i := 0; i < 4; i++ {
|
|
sig := v[i : i+1]
|
|
if sig != "0" {
|
|
nonZero = i
|
|
break
|
|
}
|
|
}
|
|
ipv6List[k] = v[nonZero:4]
|
|
}
|
|
ipv6 = strings.TrimSuffix(remainOne(strings.Join(ipv6List, ":"), ":::", "::"), "::")
|
|
if ipv6 == "" {
|
|
ipv6 = "::0"
|
|
}
|
|
return ipv6, nil
|
|
}
|