github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/utils/string.go (about) 1 package utils 2 3 import ( 4 "math/rand" 5 "strconv" 6 "strings" 7 "unicode/utf8" 8 "unsafe" 9 ) 10 11 func RandomString(len int) string { 12 return RandomStringRange(len, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") 13 } 14 15 func RandomStringRange(length int, str string) string { 16 sb := strings.Builder{} 17 sb.Grow(length) 18 for i := 0; i < length; i++ { 19 sb.WriteByte(str[rand.Intn(len(str))]) 20 } 21 return sb.String() 22 } 23 24 func ChunkString(s string, chunkSize int) []string { 25 runes := []rune(s) 26 if len(runes) == 0 || len(runes) <= chunkSize { 27 return []string{s} 28 } 29 30 chunkLen := len(runes) / chunkSize 31 if len(runes)%chunkSize != 0 { 32 chunkLen++ 33 } 34 35 chunks := make([]string, 0, chunkLen) 36 for i := 0; i < len(runes); i += chunkSize { 37 nn := i + chunkSize 38 if nn > len(runes) { 39 nn = len(runes) 40 } 41 chunks = append(chunks, string(runes[i:nn])) 42 } 43 return chunks 44 } 45 46 func ConvertSubVersionToInt(str string) int32 { 47 i, _ := strconv.ParseInt(strings.Join(strings.Split(str, "."), ""), 10, 32) 48 return int32(i) * 10 49 } 50 51 // B2S converts byte slice to a string without memory allocation. 52 func B2S(b []byte) string { 53 size := len(b) 54 if size == 0 { 55 return "" 56 } 57 return unsafe.String(&b[0], size) 58 } 59 60 // S2B converts string to a byte slice without memory allocation. 61 // 62 // Note it may break if string and/or slice header will change 63 // in the future go versions. 64 func S2B(s string) (b []byte) { 65 return unsafe.Slice(unsafe.StringData(s), len(s)) 66 } 67 68 const ( 69 escQuot = """ // shorter than """ 70 escApos = "'" // shorter than "'" 71 escAmp = "&" 72 escLT = "<" 73 escGT = ">" 74 escTab = "	" 75 escNL = "
" 76 escCR = "
" 77 escFFFD = "\uFFFD" // Unicode replacement character 78 ) 79 80 func isInCharacterRange(r rune) (inrange bool) { 81 return r == 0x09 || 82 r == 0x0A || 83 r == 0x0D || 84 r >= 0x20 && r <= 0xD7FF || 85 r >= 0xE000 && r <= 0xFFFD || 86 r >= 0x10000 && r <= 0x10FFFF 87 } 88 89 // XmlEscape xml escape string 90 func XmlEscape(s string) string { 91 var esc string 92 var sb strings.Builder 93 sb.Grow(len(s)) 94 last := 0 95 for i, r := range s { 96 width := utf8.RuneLen(r) 97 switch r { 98 case '"': 99 esc = escQuot 100 case '\'': 101 esc = escApos 102 case '&': 103 esc = escAmp 104 case '<': 105 esc = escLT 106 case '>': 107 esc = escGT 108 case '\t': 109 esc = escTab 110 case '\n': 111 esc = escNL 112 case '\r': 113 esc = escCR 114 default: 115 if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) { 116 esc = escFFFD 117 break 118 } 119 continue 120 } 121 sb.WriteString(s[last:i]) 122 sb.WriteString(esc) 123 last = i + width 124 } 125 sb.WriteString(s[last:]) 126 return sb.String() 127 }