first commit

This commit is contained in:
Yangtao
2025-11-18 17:48:20 +08:00
commit 6e56cab848
196 changed files with 65809 additions and 0 deletions

71
pkg/htools/HttpClient.go Normal file
View File

@ -0,0 +1,71 @@
package htools
import (
"io/ioutil"
"net/http"
"strings"
)
// 调用POST请求
func HttpPost(url string, body string) (remoteResponse string, err error) {
bodyReader := strings.NewReader(body)
//application/x-www-form-urlencoded
//application/json
response, err1 := http.Post(url, "application/x-www-form-urlencoded", bodyReader)
if err1 != nil {
err = err1
return
}
defer response.Body.Close()
resBody, err2 := ioutil.ReadAll(response.Body)
if err2 != nil {
err = err2
return
}
remoteResponse = string(resBody)
return
}
// 复杂http请求
func HttpDo(httpMethod string, url string, headerMap map[string]string, rawBody string) (remoteResponse string, err error) {
client := &http.Client{}
req, err0 := http.NewRequest(httpMethod, url, strings.NewReader(rawBody))
if err0 != nil {
err = err0
return
}
if len(headerMap) > 0 {
for k, v := range headerMap {
req.Header.Set(k, v)
}
}
resp, err1 := client.Do(req)
if err1 != nil {
err = err1
return
}
defer resp.Body.Close()
body, err2 := ioutil.ReadAll(resp.Body)
if err2 != nil {
err = err2
return
}
remoteResponse = string(body)
return
}

47
pkg/htools/Random.go Normal file
View File

@ -0,0 +1,47 @@
package htools
import (
"math/rand"
"time"
)
func GetVericode() string {
result := RandNumber()
return result
}
func RandInt64(min, max int64) int64 {
if min >= max || min == 0 || max == 0 {
return max
}
return rand.Int63n(max-min) + min
}
func RandNumber() string {
str := "0123456789"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 4; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
// 生成随机字符串
func GetRandomString(l int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyz"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}

146
pkg/htools/RsaUtils.go Normal file
View File

@ -0,0 +1,146 @@
package htools
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
)
// RSA加密
func RsaEncrypt(origData string, publicKey string) (string, error) {
block, _ := pem.Decode([]byte(publicKey)) // 将密钥解析成公钥实例
if block == nil {
return "", errors.New("public key error")
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) // 解析pem.Decode返回的Block指针实例
if err != nil {
return "", err
}
pub := pubInterface.(*rsa.PublicKey)
partLen := pub.N.BitLen()/8 - 11
chunks := ByteSplit([]byte(origData), partLen)
buffer := bytes.NewBufferString("")
for _, chunk := range chunks {
bytes, err := rsa.EncryptPKCS1v15(rand.Reader, pub, chunk)
if err != nil {
return "", err
}
buffer.Write(bytes)
}
return base64.StdEncoding.EncodeToString(buffer.Bytes()), nil
}
// RSA解密
func RsaDecrypt(ciphertext string, privateKey string) (string, error) {
block, _ := pem.Decode([]byte(privateKey))
if block == nil {
return "", errors.New("private key error!")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return "", err
}
partLen := priv.N.BitLen() / 8
raw, err := base64.StdEncoding.DecodeString(ciphertext)
chunks := ByteSplit([]byte(raw), partLen)
buffer := bytes.NewBufferString("")
for _, chunk := range chunks {
decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, priv, chunk)
if err != nil {
return "", err
}
buffer.Write(decrypted)
}
return buffer.String(), err
}
// RSA SHA1加签
func RsaSHA1Sign(data string, privateKey string) (string, error) {
block, _ := pem.Decode([]byte(privateKey))
if block == nil {
return "", errors.New("Sign private key decode error")
}
prk8, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return "", err
}
h := sha1.New()
h.Write([]byte(data))
hashed := h.Sum(nil)
sign, err := rsa.SignPKCS1v15(rand.Reader, prk8, crypto.SHA1, hashed)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(sign), err
}
// RSA SHA1验签
func RsaSHA1Verify(data string, sign string, publicKey string) error {
h := sha1.New()
h.Write([]byte(data))
hashed := h.Sum(nil)
decodedSign, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
return err
}
block, _ := pem.Decode([]byte(publicKey))
if block == nil {
return errors.New("Sign public key decode error")
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) // 解析pem.Decode返回的Block指针实例
if err != nil {
return err
}
pub := pubInterface.(*rsa.PublicKey)
return rsa.VerifyPKCS1v15(pub, crypto.SHA1, hashed, decodedSign)
}

View File

@ -0,0 +1,23 @@
package htools
import (
"bytes"
"fmt"
)
type StringBuilder struct {
buf bytes.Buffer
}
func NewStringBuilder() *StringBuilder {
return &StringBuilder{buf: bytes.Buffer{}}
}
func (this *StringBuilder) Append(obj interface{}) *StringBuilder {
this.buf.WriteString(fmt.Sprintf("%v", obj))
return this
}
func (this *StringBuilder) ToString() string {
return this.buf.String()
}

335
pkg/htools/Tools.go Normal file
View File

@ -0,0 +1,335 @@
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 interface{}) []interface{} {
v := reflect.ValueOf(arr)
if v.Kind() != reflect.Slice {
panic("toslice arr not slice")
}
l := v.Len()
ret := make([]interface{}, l)
for i := 0; i < l; i++ {
ret[i] = v.Index(i).Interface()
}
return ret
}
// 从字符串数组随机获取一个数组
func GetRandArrayFromArray(sourceArr []interface{}, resultCount int) (resultArr []interface{}) {
// 结果
resultArr = make([]interface{}, 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 interface{}) string {
b, _ := json.Marshal(v)
return string(b)
}

102
pkg/htools/UUID.go Normal file
View File

@ -0,0 +1,102 @@
package htools
import (
crand "crypto/rand"
"encoding/hex"
"errors"
"fmt"
mrand "math/rand"
"regexp"
"strings"
)
// seeded indicates if math/rand has been seeded
var seeded bool = false
// uuidRegex matches the UUID string
var uuidRegex *regexp.Regexp = regexp.MustCompile(`^\{?([a-fA-F0-9]{8})-?([a-fA-F0-9]{4})-?([a-fA-F0-9]{4})-?([a-fA-F0-9]{4})-?([a-fA-F0-9]{12})\}?$`)
// UUID type.
type UUID [16]byte
// Hex returns a hex string representation of the UUID in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
func (this UUID) Hex() string {
x := [16]byte(this)
return fmt.Sprintf("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
x[0], x[1], x[2], x[3], x[4],
x[5], x[6],
x[7], x[8],
x[9], x[10], x[11], x[12], x[13], x[14], x[15])
}
// Rand generates a new version 4 UUID.
func Rand() UUID {
var x [16]byte
randBytes(x[:])
x[6] = (x[6] & 0x0F) | 0x40
x[8] = (x[8] & 0x3F) | 0x80
return x
}
// FromStr returns a UUID based on a string.
// The string could be in the following format:
//
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
//
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
//
// If the string is not in one of these formats, it'll return an error.
func FromStr(s string) (id UUID, err error) {
if s == "" {
err = errors.New("Empty string")
return
}
parts := uuidRegex.FindStringSubmatch(s)
if parts == nil {
err = errors.New("Invalid string format")
return
}
var array [16]byte
slice, _ := hex.DecodeString(strings.Join(parts[1:], ""))
copy(array[:], slice)
id = array
return
}
// MustFromStr behaves similarly to FromStr except that it'll panic instead of
// returning an error.
func MustFromStr(s string) UUID {
id, err := FromStr(s)
if err != nil {
panic(err)
}
return id
}
// randBytes uses crypto random to get random numbers. If fails then it uses math random.
func randBytes(x []byte) {
length := len(x)
n, err := crand.Read(x)
if n != length || err != nil {
for length > 0 {
length--
x[length] = byte(mrand.Int31n(256))
}
}
}
func GetUUID() string {
var uuid UUID = Rand()
return uuid.Hex()
}