init
This commit is contained in:
38
utils/array.go
Normal file
38
utils/array.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package utils
|
||||
|
||||
import "strings"
|
||||
|
||||
func In(target string, array []string) bool {
|
||||
target = strings.Trim(target, "")
|
||||
for _, v := range array {
|
||||
if strings.Trim(v, "") == target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 字符串数组是否存在
|
||||
func StrArrayIndex(items []string, item string) int {
|
||||
for i, eachItem := range items {
|
||||
if eachItem == item {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func RemoveRepeatSlice(in []string) (out []string) {
|
||||
_map := make(map[string]bool)
|
||||
for i := 0; i < len(in); i++ {
|
||||
if in[i] != "" {
|
||||
_map[in[i]] = true
|
||||
}
|
||||
}
|
||||
|
||||
for key, _ := range _map {
|
||||
out = append(out, key)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
106
utils/convert.go
Normal file
106
utils/convert.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 字符串转Int
|
||||
//
|
||||
// intStr:数字的字符串
|
||||
func String2Int(intStr string) (intNum int) {
|
||||
intNum, _ = strconv.Atoi(intStr)
|
||||
return
|
||||
}
|
||||
|
||||
// 字符串转Int64
|
||||
//
|
||||
// intStr:数字的字符串
|
||||
func String2Int64(intStr string) (int64Num int64) {
|
||||
intNum, _ := strconv.Atoi(intStr)
|
||||
int64Num = int64(intNum)
|
||||
return
|
||||
}
|
||||
|
||||
// 字符串转Float64
|
||||
//
|
||||
// floatStr:小数点数字的字符串
|
||||
func String2Float64(floatStr string) (floatNum float64) {
|
||||
floatNum, _ = strconv.ParseFloat(floatStr, 64)
|
||||
return
|
||||
}
|
||||
|
||||
// 字符串转Float32
|
||||
//
|
||||
// floatStr:小数点数字的字符串
|
||||
func String2Float32(floatStr string) (floatNum float32) {
|
||||
floatNum64, _ := strconv.ParseFloat(floatStr, 32)
|
||||
floatNum = float32(floatNum64)
|
||||
return
|
||||
}
|
||||
|
||||
// Int转字符串
|
||||
//
|
||||
// intNum:数字字符串
|
||||
func Int2String(intNum int) (intStr string) {
|
||||
intStr = strconv.Itoa(intNum)
|
||||
return
|
||||
}
|
||||
|
||||
// Int64转字符串
|
||||
//
|
||||
// intNum:数字字符串
|
||||
func Int642String(intNum int64) (int64Str string) {
|
||||
//10, 代表10进制
|
||||
int64Str = strconv.FormatInt(intNum, 10)
|
||||
return
|
||||
}
|
||||
|
||||
// Float64转字符串
|
||||
//
|
||||
// floatNum:float64数字
|
||||
// prec:精度位数(不传则默认float数字精度)
|
||||
func Float64ToString(floatNum float64, prec ...int) (floatStr string) {
|
||||
if len(prec) > 0 {
|
||||
floatStr = strconv.FormatFloat(floatNum, 'f', prec[0], 64)
|
||||
return
|
||||
}
|
||||
floatStr = strconv.FormatFloat(floatNum, 'f', -1, 64)
|
||||
return
|
||||
}
|
||||
|
||||
// Float32转字符串
|
||||
//
|
||||
// floatNum:float32数字
|
||||
// prec:精度位数(不传则默认float数字精度)
|
||||
func Float32ToString(floatNum float32, prec ...int) (floatStr string) {
|
||||
if len(prec) > 0 {
|
||||
floatStr = strconv.FormatFloat(float64(floatNum), 'f', prec[0], 32)
|
||||
return
|
||||
}
|
||||
floatStr = strconv.FormatFloat(float64(floatNum), 'f', -1, 32)
|
||||
return
|
||||
}
|
||||
|
||||
// 二进制转10进制
|
||||
func BinaryToDecimal(bit string) (num int) {
|
||||
fields := strings.Split(bit, "")
|
||||
lens := len(fields)
|
||||
var tempF float64 = 0
|
||||
for i := 0; i < lens; i++ {
|
||||
floatNum := String2Float64(fields[i])
|
||||
tempF += floatNum * math.Pow(2, float64(lens-i-1))
|
||||
}
|
||||
num = int(tempF)
|
||||
return
|
||||
}
|
||||
|
||||
// interface to string
|
||||
func AnyToString(in any) (s string) {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return in.(string)
|
||||
}
|
||||
25
utils/crypto.go
Normal file
25
utils/crypto.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//Md5 .
|
||||
func Md5(src string) string {
|
||||
data := []byte(src)
|
||||
has := md5.Sum(data)
|
||||
md5str := fmt.Sprintf("%x", has)
|
||||
return md5str
|
||||
}
|
||||
|
||||
func Sha256(src, privateKey string) string {
|
||||
s := []byte(src)
|
||||
key := []byte(privateKey)
|
||||
m := hmac.New(sha256.New, key)
|
||||
m.Write(s)
|
||||
return hex.EncodeToString(m.Sum(nil))
|
||||
}
|
||||
35
utils/dir.go
Normal file
35
utils/dir.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func PathExists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsExist(err) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 创建文件夹
|
||||
func CreateDir(dirName string) bool {
|
||||
err := os.Mkdir(dirName, 0755)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetRunPath() string {
|
||||
path, _ := os.Executable()
|
||||
return path
|
||||
}
|
||||
|
||||
func GetCurrentPath() string {
|
||||
path, _ := os.Getwd()
|
||||
return path
|
||||
}
|
||||
35
utils/ext.go
Normal file
35
utils/ext.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func If(condition bool, trueValue, falseValue interface{}) interface{} {
|
||||
if condition {
|
||||
return trueValue
|
||||
}
|
||||
return falseValue
|
||||
}
|
||||
|
||||
//如果首字母是小写字母, 则变换为大写字母
|
||||
func FirstToUpper(str string) string {
|
||||
if str == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.ToUpper(str[:1]) + strings.ToLower(str[1:])
|
||||
}
|
||||
|
||||
func ParseParams(in map[string]string) map[string]interface{} {
|
||||
out := make(map[string]interface{})
|
||||
for k, v := range in {
|
||||
fv, err := strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
out[k] = fv
|
||||
} else {
|
||||
out[k] = v
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
20
utils/file.go
Normal file
20
utils/file.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func StringToFile(path, content string) error {
|
||||
startF, err := os.Create(path)
|
||||
if err != nil {
|
||||
return errors.New("os.Create create file " + path + " error:" + err.Error())
|
||||
}
|
||||
defer startF.Close()
|
||||
_, err = io.WriteString(startF, content)
|
||||
if err != nil {
|
||||
return errors.New("io.WriteString to " + path + " error:" + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
10
utils/identity.go
Normal file
10
utils/identity.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
ulid "github.com/oklog/ulid/v2"
|
||||
)
|
||||
|
||||
// remove nanoid,uuid,replace to ulid
|
||||
func ULID() string {
|
||||
return ulid.Make().String()
|
||||
}
|
||||
13
utils/json.go
Normal file
13
utils/json.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package utils
|
||||
|
||||
import "strings"
|
||||
|
||||
func JsonEscape(in string) string {
|
||||
in = strings.ReplaceAll(in, "\n", "")
|
||||
in = strings.ReplaceAll(in, "\t", "")
|
||||
in = strings.ReplaceAll(in, "\r", "")
|
||||
in = strings.ReplaceAll(in, "\r\n", "")
|
||||
in = strings.ReplaceAll(in, "\\\"", "\"")
|
||||
in = strings.ReplaceAll(in, "\\\\", "\\")
|
||||
return in
|
||||
}
|
||||
213
utils/net.go
Normal file
213
utils/net.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func IsPublicIP(ipString string) bool {
|
||||
ip := net.ParseIP(ipString)
|
||||
if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() {
|
||||
return false
|
||||
}
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
switch true {
|
||||
case ip4[0] == 10:
|
||||
return false
|
||||
case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
|
||||
return false
|
||||
case ip4[0] == 192 && ip4[1] == 168:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Get Location IP .
|
||||
func GetLocationIP() string {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
ip := ""
|
||||
for _, a := range addrs {
|
||||
if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
ip = ipnet.IP.String()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if ip == "" {
|
||||
return ""
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
func LocalIPv4s() ([]string, error) {
|
||||
|
||||
var ips []string
|
||||
addrs, _ := net.InterfaceAddrs()
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
locIP := ipnet.IP.To4().String()
|
||||
if locIP[0:7] != "169.254" {
|
||||
ips = append(ips, locIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
func GetOutBoundIP() (ip string, err error) {
|
||||
body, err := HttpGet("http://ip.dhcp.cn/?ip") // 获取外网 IP
|
||||
return string(body), err
|
||||
}
|
||||
|
||||
func HttpGet(url string) ([]byte, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
// handle error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
|
||||
return body, err
|
||||
}
|
||||
|
||||
func HttpPost(url string, header map[string]string, data []byte) ([]byte, error) {
|
||||
var err error
|
||||
reader := bytes.NewBuffer(data)
|
||||
request, err := http.NewRequest("POST", url, reader)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
|
||||
request.Header.Set("Request-Id", ULID())
|
||||
|
||||
for key, val := range header {
|
||||
request.Header.Set(key, val)
|
||||
}
|
||||
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New(string(respBytes))
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
func HttpRequest(r *http.Request) ([]byte, error) {
|
||||
var err error
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
func DownloadFile(url, saveTo string, fb func(length, downLen int64)) {
|
||||
var (
|
||||
fsize int64
|
||||
buf = make([]byte, 32*1024)
|
||||
written int64
|
||||
)
|
||||
//创建一个http client
|
||||
client := new(http.Client)
|
||||
//get方法获取资源
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
fmt.Printf("download %s error:%s\n", url, err)
|
||||
os.Exit(0)
|
||||
}
|
||||
//读取服务器返回的文件大小
|
||||
fsize, err = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 32)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//创建文件
|
||||
file, err := os.Create(saveTo)
|
||||
file.Chmod(0777)
|
||||
if err != nil {
|
||||
fmt.Printf("Create %s error:%s\n", saveTo, err)
|
||||
os.Exit(0)
|
||||
}
|
||||
defer file.Close()
|
||||
if resp.Body == nil {
|
||||
fmt.Printf("resp %s error:%s\n", url, err)
|
||||
os.Exit(0)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
//下面是 io.copyBuffer() 的简化版本
|
||||
for {
|
||||
//读取bytes
|
||||
nr, er := resp.Body.Read(buf)
|
||||
if nr > 0 {
|
||||
//写入bytes
|
||||
nw, ew := file.Write(buf[0:nr])
|
||||
//数据长度大于0
|
||||
if nw > 0 {
|
||||
written += int64(nw)
|
||||
}
|
||||
//写入出错
|
||||
if ew != nil {
|
||||
err = ew
|
||||
break
|
||||
}
|
||||
//读取是数据长度不等于写入的数据长度
|
||||
if nr != nw {
|
||||
err = io.ErrShortWrite
|
||||
break
|
||||
}
|
||||
}
|
||||
if er != nil {
|
||||
if er != io.EOF {
|
||||
err = er
|
||||
}
|
||||
break
|
||||
}
|
||||
//没有错误了快使用 callback
|
||||
|
||||
fb(fsize, written)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("callback error:%s\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
49
utils/random.go
Normal file
49
utils/random.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
)
|
||||
|
||||
// 随机生成字符串
|
||||
func RandomString(l int) string {
|
||||
str := "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
|
||||
bytes := []byte(str)
|
||||
var result []byte = make([]byte, 0, l)
|
||||
for i := 0; i < l; i++ {
|
||||
result = append(result, bytes[rand.IntN(len(bytes))])
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// 随机生成纯字符串
|
||||
func RandomPureString(l int) string {
|
||||
str := "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
|
||||
bytes := []byte(str)
|
||||
var result []byte = make([]byte, 0, l)
|
||||
for i := 0; i < l; i++ {
|
||||
result = append(result, bytes[rand.IntN(len(bytes))])
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// 随机生成纯大写字符串
|
||||
func RandomPureUpString(l int) string {
|
||||
str := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
bytes := []byte(str)
|
||||
var result []byte = make([]byte, 0, l)
|
||||
for i := 0; i < l; i++ {
|
||||
result = append(result, bytes[rand.IntN(len(bytes))])
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// 随机生成数字字符串
|
||||
func RandomNumber(l int) string {
|
||||
str := "0123456789"
|
||||
bytes := []byte(str)
|
||||
var result []byte
|
||||
for i := 0; i < l; i++ {
|
||||
result = append(result, bytes[rand.IntN(len(bytes))])
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
39
utils/ticker.go
Normal file
39
utils/ticker.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
func SetTimeout(f func(), timeout int) context.CancelFunc {
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-time.After(time.Duration(timeout) * time.Second):
|
||||
f()
|
||||
}
|
||||
}()
|
||||
return cancelFunc
|
||||
}
|
||||
|
||||
func SetInterval(what func(), delay time.Duration) chan bool {
|
||||
ticker := time.NewTicker(delay)
|
||||
stopIt := make(chan bool)
|
||||
go func() {
|
||||
|
||||
for {
|
||||
|
||||
select {
|
||||
case <-stopIt:
|
||||
return
|
||||
case <-ticker.C:
|
||||
what()
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
// return the bool channel to use it as a stopper
|
||||
return stopIt
|
||||
}
|
||||
Reference in New Issue
Block a user