Files
servicebase/pkg/htools/Tools.go
2025-11-19 14:24:13 +08:00

336 lines
6.1 KiB
Go

package htools
import (
"bytes"
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/rand"
"reflect"
"sort"
"strconv"
"strings"
"time"
)
// MD5加密
func StringToMD5(waitMD5string string) string {
h := md5.New()
h.Write([]byte(waitMD5string))
cipherStr := h.Sum(nil)
result := hex.EncodeToString(cipherStr)
return result
}
// SHA1加密
func StringToSHA1(waitMD5string string) string {
h := sha1.New()
h.Write([]byte(waitMD5string))
cipherStr := h.Sum(nil)
result := hex.EncodeToString(cipherStr)
return result
}
// HMAC SHA1
func StringToHmacSha1(waitShaString, keyStr string) string {
key := []byte(keyStr)
mac := hmac.New(sha1.New, key)
mac.Write([]byte(waitShaString))
result := hex.EncodeToString(mac.Sum(nil))
return result
}
// 字符串转int64
func StringToInt64(waitString string) int64 {
stringInt64, err := strconv.ParseInt(waitString, 10, 64)
if err != nil {
return 0
}
return stringInt64
}
// 字符串转int32
func StringToInt(waitString string) int {
if waitString == "" {
return 0
}
stringInt, err := strconv.Atoi(waitString)
if err != nil {
return 0
}
return stringInt
}
func StringNumPlus(v1, v2 string) string {
return strconv.Itoa(StringToInt(v1) + StringToInt(v2))
}
// 字符串转float64
func StringToFloat64(waitString string) float64 {
stringInt64, err := strconv.ParseFloat(waitString, 64)
if err != nil {
return 0
}
return stringInt64
}
// float64保留2位
func Float64Decimal(waitFloatValue float64) float64 {
value, err := strconv.ParseFloat(fmt.Sprintf("%.2f", waitFloatValue), 64)
if err != nil {
return 0
}
return value
}
// strconv.FormatFloat(float64, 'E', -1, 64)
// float64转字符串
func Float64ToString(waitFloat64 float64) string {
stringInt64 := strconv.FormatFloat(waitFloat64, 'f', -1, 64)
return stringInt64
}
// 截取字符串
func Substr(str string, start int, length int) string {
rs := []rune(str)
rl := len(rs)
end := 0
if start < 0 {
start = rl - 1 + start
}
end = start + length
if start > end {
start, end = end, start
}
if start < 0 {
start = 0
}
if start > rl {
start = rl
}
if end < 0 {
end = 0
}
if end > rl {
end = rl
}
return string(rs[start:end])
}
// map转html
func MapToXML(mapData map[string]string) string {
if len(mapData) == 0 {
return ""
}
sb := NewStringBuilder()
sb.Append("<xml>")
for key, val := range mapData {
sb.Append("<" + key + ">")
sb.Append(val)
sb.Append("</" + key + ">")
}
sb.Append("</xml>")
return sb.ToString()
}
// 获取当前年周
func GetCurrentYearWeek() string {
year, week := time.Now().ISOWeek()
return strconv.Itoa(year) + strconv.Itoa(week)
}
// 字符串转time类型
func StringToTime(dateString string) time.Time {
// 获取本地location
toBeCharge := dateString // 待转化为时间戳的字符串 注意 这里的小时和分钟还要秒必须写 因为是跟着模板走的 修改模板的话也可以不写
timeLayout := "2006-01-02 15:04:05" // 转化所需模板
loc, _ := time.LoadLocation("Local") // 重要:获取时区
theTime, _ := time.ParseInLocation(timeLayout, toBeCharge, loc) // 使用模板在对应时区转化为time.time类型
//sr := theTime.Unix() // 转化为时间戳 类型是int64
// 时间戳转日期
//dataTimeStr := time.Unix(sr, 0).Format(timeLayout) // 设置时间戳 使用模板格式化为日期字符串
return theTime
}
// 判断数组是否包含某个元素
func CheckStringIsInArray(arrayList []string, element string) bool {
if len(arrayList) == 0 {
return false
}
isInArray := false
for _, data := range arrayList {
if data == element {
isInArray = true
break
}
}
return isInArray
}
// slice to 字符串
func StringListToString(stringList []string, split string) string {
if len(split) == 0 {
split = ","
}
return strings.Replace(strings.Trim(fmt.Sprint(stringList), "[]"), " ", split, -1)
}
// map 转 url参数
func MapToUrlParams(mapData map[string]string) string {
mapLen := len(mapData)
if mapLen == 0 {
return ""
}
sb := NewStringBuilder()
i := 0
for k, v := range mapData {
sb.Append(k + "=" + v)
if i < mapLen-1 {
sb.Append("&")
}
i++
}
return sb.ToString()
}
// []byte 合并
func BytesCombine(pBytes ...[]byte) []byte {
return bytes.Join(pBytes, []byte(""))
}
// 获取当前UTC时间 秒数
func GetCurrentUtcTimeSecond() int64 {
return time.Now().UTC().Unix()
}
// byte数组分组
func ByteSplit(buf []byte, lim int) [][]byte {
var chunk []byte
chunks := make([][]byte, 0, len(buf)/lim+1)
for len(buf) >= lim {
chunk, buf = buf[:lim], buf[lim:]
chunks = append(chunks, chunk)
}
bufLen := len(buf)
if bufLen > 0 {
chunks = append(chunks, buf[:bufLen])
}
return chunks
}
// 强类型数组转为interface类型的数组
func ToSlice(arr any) []any {
v := reflect.ValueOf(arr)
if v.Kind() != reflect.Slice {
panic("toslice arr not slice")
}
l := v.Len()
ret := make([]any, l)
for i := 0; i < l; i++ {
ret[i] = v.Index(i).Interface()
}
return ret
}
// 从字符串数组随机获取一个数组
func GetRandArrayFromArray(sourceArr []any, resultCount int) (resultArr []any) {
// 结果
resultArr = make([]any, 0)
if len(sourceArr) < resultCount {
return
}
r1 := rand.New(rand.NewSource(time.Now().UnixNano()))
for _, k := range r1.Perm(len(sourceArr)) {
if len(resultArr) >= resultCount {
break
}
val := sourceArr[k]
resultArr = append(resultArr, val)
}
return
}
func RelationKey(userIds ...string) (key string) {
sort.Strings(userIds)
return strings.Join(userIds, "")
}
func ApplyKey(userIds ...string) (key string) {
return strings.Join(userIds, "")
}
func IPToUint32(ip string) (uint32, error) {
ips := strings.Split(ip, ".")
if len(ips) != 4 {
return 0, errors.New("ip error")
}
num := uint64(0)
for i, item := range ips {
n, _ := strconv.ParseUint(item, 10, 32)
num += n << (8 * uint(3-i))
}
return uint32(num), nil
}
func JsonStr(v any) string {
b, _ := json.Marshal(v)
return string(b)
}