// // str_helper.go // Copyright (C) 2022 tiglog // // 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] } func GetCjkRange(code int) string { var result string if code >= 0x4E00 && code <= 0x9FFF { result = "CJK" } else if code >= 0x3400 && code <= 0x4DBF { result = "EXT-A" } else if code >= 0x20000 && code <= 0x2A6DF { result = "EXT-B" } else if code >= 0x2A700 && code <= 0x2B739 { result = "EXT-C" } else if code >= 0x2B740 && code <= 0x2B81D { result = "EXT-D" } else if code >= 0x2B820 && code <= 0x2CEA1 { result = "EXT-E" } else if code >= 0x2CEB0 && code <= 0x2EBE0 { result = "EXT-F" } else if code >= 0x30000 && code <= 0x3134A { result = "EXT-G" } else if code >= 0x31350 && code <= 0x323AF { result = "EXT-H" } else if code >= 0x2EBF0 && code <= 0x2EE5D { result = "EXT-I" } else if code == 0x3007 { result = "零" } else if code >= 0x31C0 && code <= 0x31EF { result = "笔画" } else if code >= 0x2E80 && code <= 0x2EFF { result = "部首补充" } else if code >= 0xE000 && code <= 0xF8FF { result = "PUA" } else if code >= 0x2F00 && code <= 0x2FDF { result = "康熙部首" } else if code >= 0xF900 && code <= 0xFAD9 { result = "兼容区" } else if code >= 0xFE30 && code <= 0xFE4F { result = "兼容形式" } else if code >= 0x2F800 && code <= 0x2FA1D { result = "兼容表意文字增补" } else if code >= 0x3100 && code <= 0x312F { result = "注音" } else if code >= 0x17000 && code <= 0x187F7 { result = "西夏文" } else if code >= 0x18800 && code <= 0x18AFF { result = "西夏文部首" } else if code >= 0x18D00 && code <= 0x18D08 { result = "西夏文增补" } else if code >= 0x18B00 && code <= 0x18CFF { result = "契丹文" } else if code >= 0x0900 && code <= 0x097F { result = "梵文" } else if code >= 0x1B170 && code <= 0x1B2FF { result = "女书" } else if code >= 0x0F00 && code <= 0x0FFF { result = "藏文" } else if code >= 0x1800 && code <= 0x18AF { result = "蒙古语" } else if code >= 0x30A0 && code <= 0x30FF { result = "日文片假名" } else if code >= 0x31F0 && code <= 0x31FF { result = "片假名扩展" } else if code >= 0x3040 && code <= 0x309F { result = "日文平假名" } else if code >= 0x3000 && code <= 0x303F { result = "符号和标点符号" } else if code >= 0x2E00 && code <= 0x2E7F { result = "补充标点符号" } else if code >= 0x2200 && code <= 0x22FF { result = "数学运算符号" } else if code >= 0x2A00 && code <= 0x2AFF { result = "补充数学运算符" } else if code >= 0x2150 && code <= 0x218F { result = "数字形式符号" } else if code >= 0x2300 && code <= 0x23FF { result = "杂项技术符号" } else if code >= 0x27C0 && code <= 0x27EF { result = "杂项数学符号-A" } else if code >= 0x2980 && code <= 0x29FF { result = "杂项数学符号-B" } else if code >= 0x2190 && code <= 0x21FF { result = "箭头符号" } else if code >= 0x3190 && code <= 0x319F { result = "汉文训读" } else if code >= 0x3200 && code <= 0x32FF { result = "带圈字符及月份" } else if code >= 0x1F100 && code <= 0x1F1FF { result = "带圈字母数字补充" } else if code >= 0x1F200 && code <= 0x1F2FF { result = "带圈表意文字补充" } else if code >= 0x1D100 && code <= 0x1D1FF { result = "音乐符号" } else if code >= 0x1D360 && code <= 0x1D37F { result = "算筹" } else if code >= 0x1D300 && code <= 0x1D35F { result = "太玄经符号" } else if code >= 0x1F600 && code <= 0x1F64F { result = "表情符号" } else if code >= 0x2070 && code <= 0x209F { result = "上下标" } else if code >= 0x1D400 && code <= 0x1D7FF { result = "字母和数字符号" } else if code >= 0x25A0 && code <= 0x25FF { result = "几何形状" } else if code >= 0x1F780 && code <= 0x1F7FF { result = "几何图形扩展" } else if code >= 0x2630 && code <= 0x2637 { result = "八卦" } else if code >= 0x19904 && code <= 0x19967 { result = "易经六十四卦符号" } else if code >= 0x1FA00 && code <= 0x1FA6F { result = "象棋符号" } else if code >= 0x0370 && code <= 0x03FF { result = "希腊语和科普特语" } else if code >= 0x1F000 && code <= 0x1F02F { result = "麻将牌" } else if code >= 0x1F0A0 && code <= 0x1F0FF { result = "扑克牌" } else if code >= 0x20A0 && code <= 0x20CF { result = "货币符号" } else if code >= 0x1F680 && code <= 0x1F6FF { result = "交通和地图符号" } else if code >= 0x1F030 && code <= 0x1F09F { result = "多米诺骨牌" } else if code >= 0x1F300 && code <= 0x1F5FF { result = "杂项符号和象形文字" } else if code >= 0x2500 && code <= 0x257F { result = "方框绘制字符" } else if code >= 0x1F700 && code <= 0x1F77F { result = "炼金术符号" } return result } // 获取某个字的 unicode 值 func Ord(in string) int { s := []rune(in) return int(s[0]) } // 把 unicode 值转成字符串 func Chr(code int) string { return string(rune(code)) }