165 lines
3.0 KiB
Go
165 lines
3.0 KiB
Go
//
|
||
// str_helper.go
|
||
// Copyright (C) 2022 tiglog <me@tiglog.com>
|
||
//
|
||
// Distributed under terms of the MIT license.
|
||
//
|
||
|
||
package helper
|
||
|
||
import (
|
||
"math/rand"
|
||
"strings"
|
||
"time"
|
||
"unicode"
|
||
|
||
"git.hexq.cn/tiglog/golib/crypto/gmd5"
|
||
"github.com/rs/xid"
|
||
)
|
||
|
||
// 是否是字符串
|
||
func IsString(v interface{}) bool {
|
||
_, ok := v.(string)
|
||
return ok
|
||
}
|
||
|
||
// 随机字符串
|
||
func RandString(n int) string {
|
||
letterRunes := []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||
rand.Seed(time.Now().UnixNano())
|
||
b := make([]rune, n)
|
||
for i := range b {
|
||
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||
}
|
||
return string(b)
|
||
}
|
||
|
||
// 首字母大写
|
||
func UcFirst(str string) string {
|
||
for _, v := range str {
|
||
u := string(unicode.ToUpper(v))
|
||
return u + str[len(u):]
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// 首字母小写
|
||
func LcFirst(str string) string {
|
||
for _, v := range str {
|
||
u := string(unicode.ToLower(v))
|
||
return u + str[len(u):]
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// 驼峰转蛇形, XxYy => xx_yy
|
||
func SnakeString(str string) string {
|
||
data := make([]byte, 0, len(str)*2)
|
||
j := false
|
||
num := len(str)
|
||
for i := 0; i < num; i++ {
|
||
d := str[i]
|
||
if i > 0 && d >= 'A' && d <= 'Z' && j {
|
||
data = append(data, '_')
|
||
}
|
||
if d != '_' {
|
||
j = true
|
||
}
|
||
data = append(data, d)
|
||
}
|
||
return strings.ToLower(string(data[:]))
|
||
}
|
||
|
||
// 蛇形转驼峰, xx_yy => XxYy
|
||
func CamelString(str string) string {
|
||
data := make([]byte, 0, len(str))
|
||
j := false
|
||
k := false
|
||
num := len(str) - 1
|
||
for i := 0; i <= num; i++ {
|
||
d := str[i]
|
||
if k == false && d >= 'A' && d <= 'Z' {
|
||
k = true
|
||
}
|
||
if d >= 'a' && d <= 'z' && (j || k == false) {
|
||
d = d - 32
|
||
j = false
|
||
k = true
|
||
}
|
||
if k && d == '_' && num > i && str[i+1] >= 'a' && str[i+1] <= 'z' {
|
||
j = true
|
||
continue
|
||
}
|
||
data = append(data, d)
|
||
}
|
||
return string(data[:])
|
||
}
|
||
|
||
// 乱序字符串
|
||
func Shuffle(str string) string {
|
||
if str == "" {
|
||
return str
|
||
}
|
||
|
||
runes := []rune(str)
|
||
index := 0
|
||
|
||
for i := len(runes) - 1; i > 0; i-- {
|
||
index = rand.Intn(i + 1)
|
||
|
||
if i != index {
|
||
runes[i], runes[index] = runes[index], runes[i]
|
||
}
|
||
}
|
||
return string(runes)
|
||
}
|
||
|
||
// 反序字符串
|
||
func Reverse(str string) string {
|
||
n := len(str)
|
||
runes := make([]rune, n)
|
||
for _, r := range str {
|
||
n--
|
||
runes[n] = r
|
||
}
|
||
return string(runes[n:])
|
||
}
|
||
|
||
// 唯一字符串
|
||
// 返回字符串长度为 20
|
||
func GenId() string {
|
||
guid := xid.New()
|
||
return guid.String()
|
||
}
|
||
|
||
// 可变长度的唯一字符串
|
||
// 长度太短,可能就不唯一了
|
||
// 长度大于等于 16 为最佳
|
||
// 长度小于20时,为 GenId 的值 md5 后的前缀,因此,理论上前6位也能在大多数情况
|
||
// 下唯一
|
||
func Uniq(l int) string {
|
||
if l <= 0 {
|
||
panic("wrong length param")
|
||
}
|
||
ret := GenId()
|
||
hl := len(ret)
|
||
if l < hl {
|
||
t, err := gmd5.EncryptString(ret)
|
||
if err != nil {
|
||
return ret[hl-l:]
|
||
}
|
||
return t[:l]
|
||
}
|
||
mhac_len := 6
|
||
pl := len(ret)
|
||
var hash string
|
||
for l > pl {
|
||
hash = GenId()
|
||
hash = hash[mhac_len:]
|
||
ret += hash
|
||
pl += len(hash)
|
||
}
|
||
// log.Println("ret=", ret, ", pl=", pl, ", l=", l)
|
||
return ret[0:l]
|
||
}
|