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

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
}