This commit is contained in:
zhaoxiaorong
2025-02-07 13:01:38 +08:00
parent ebcdfe1ee8
commit 57a0d8ae81
52 changed files with 3313 additions and 0 deletions

38
utils/array.go Normal file
View 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
View 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转字符串
//
// floatNumfloat64数字
// 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转字符串
//
// floatNumfloat32数字
// 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
}