diff --git a/cryptor/rsa_private_example.pem b/cryptor/rsa_private_example.pem index e44e4a4..5e19362 100644 --- a/cryptor/rsa_private_example.pem +++ b/cryptor/rsa_private_example.pem @@ -1,51 +1,51 @@ -----BEGIN rsa private key----- -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 -----END rsa private key----- diff --git a/cryptor/rsa_public_example.pem b/cryptor/rsa_public_example.pem index f49de64..b4551ff 100644 --- a/cryptor/rsa_public_example.pem +++ b/cryptor/rsa_public_example.pem @@ -1,14 +1,14 @@ -----BEGIN rsa public key----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtKEukXkdl8ggX5I5Us0M -BcsrFzbTgwOn8u72IhJzruvsHcjlGGF5L1eXh3C0zbcoWq+Bxf8NnXvSXASZlZHT -iSVLFerxFw2LwTNcyfOz/Y/wIbtrYu4ZdttLKdJS607UvnZ57O7SQni5rxYAP5j+ -veKHEJgAO7Sn0lEEWwkeudsfVrQmQx6JHYtCtx78p2GHXPj9wXWHxWHKMkczKtmB -FDLlYocPhQfWzx87sYKjGmTMGzVddsrllAqVozlxXTQndOdozx8BWHSBiYWguOvW -iYjvryrIf0B7wn4wt3o2Yre3w4BkwrTUE73JWG2q1NLuPoT27m7WcdVFGGcKAygA -dMMSwS530v8tnAw876/w1SfUmtkIcqknysMjsvxHx1fbEfkl3b0yBnzcUrT1qxzm -NEqJSQXBtFYFyGgyeL8J1ul/T5hPSNz0we5TO/xRkX5Y1HNJ+a2r8EnE1PU8zgQG -BxYSIub4ajSUccyn5yHQ/k2FlsolZiu/UzfnzMgdg55svgf5x1ntKYBoVHuYe84A -b3WRAeVlUi0OphvFlBzfIQvrG2sRbiPZRZZ0E8kBH94zPmrFmyX+7TwlSqVHtNFc -+Ynz+hrHcd4z6N7fIb+D1gSYuukkcRqr4ANO0ugZk0YYKaWDf86H7OZOXna8ObIA -i+3gx+Wcp1lm7Ffk9sn+dGkCAwEAAQ== +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2yy8VWqASCh7YbtiJiWt +SimACGycqUgYOiaR1SR6F2rK7Xe3juHUuqI5RVZyo69Jh24jYYNgkS05XtJrmykN +jGXxtaOnLYFy+UQmor3BtgVkDKxGL4hHnGdnHIaU/btSNd0ewvYMAg/9sVK75o8Z +/4XH14iTZlLpohRaKZf7nvN5ecRaNs/eItgzUy43b2rYdIxTFDjqF1x/LIQcrb3c +6oDjGd6WwR0sEQL47EgTYNo9pbbULZ1X7h1pS9hNdAEcwZEo78TsBScQ7tPL2G1L +4PA6oxid/nOXwkJNHMv1HcZZEj6uZSgv1BP+rGWxTY0z8o+EDFR1lq3lAgc4cC2h +MsnQ7AIqhQe4vH0Gh0W+sdccuIlV0H8RDMcz9px45unqWKBo5dE7Iyqyr46j8r9w +FUUWxN7Gvh45OgRyPYs4C6BEFgyTtJnff/T9e7d7RQEKXt4Dr3fqFztbgogJwxi8 +ZpZ5CvKRO39V/YorGrGBi1cVLR8opTp7N9+pzwkZpgfh3JHZeDreEAnU8tfwu/9u +COPzDKjwrjXOs8tM4WI8ye8uw0DgXAjwqlEvGuWBGOg763zv91vZjJxsHIYr4dSE +cJG5tUM0WDETP40uhJj6TZc9iMj9vE0oHmzXPno2K2f+bWHYy3b6ea11VzJVhUu0 +xquay8VYBpMtPYzf74zuMjsCAwEAAQ== -----END rsa public key----- diff --git a/strutil/string.go b/strutil/string.go index a716cb4..4c8e8e8 100644 --- a/strutil/string.go +++ b/strutil/string.go @@ -37,16 +37,17 @@ func CamelCase(s string) string { // Capitalize converts the first character of a string to upper case and the remaining to lower case. // Play: https://go.dev/play/p/2OAjgbmAqHZ func Capitalize(s string) string { - result := make([]rune, len(s)) - for i, v := range s { - if i == 0 { - result[i] = unicode.ToUpper(v) - } else { - result[i] = unicode.ToLower(v) - } + if s == "" { + return s } - return string(result) + runes := []rune(s) + runes[0] = unicode.ToUpper(runes[0]) + for i := 1; i < len(runes); i++ { + runes[i] = unicode.ToLower(runes[i]) + } + + return string(runes) } // UpperFirst converts the first character of string to upper case. @@ -127,49 +128,57 @@ func UpperSnakeCase(s string) string { // Before returns the substring of the source string up to the first occurrence of the specified string. // Play: https://go.dev/play/p/JAWTZDS4F5w func Before(s, char string) string { - i := strings.Index(s, char) - - if s == "" || char == "" || i == -1 { + if char == "" { return s } - return s[0:i] + if i := strings.Index(s, char); i >= 0 { + return s[:i] + } + + return s } // BeforeLast returns the substring of the source string up to the last occurrence of the specified string. // Play: https://go.dev/play/p/pJfXXAoG_Te func BeforeLast(s, char string) string { - i := strings.LastIndex(s, char) - - if s == "" || char == "" || i == -1 { + if char == "" { return s } - return s[0:i] + if i := strings.LastIndex(s, char); i >= 0 { + return s[:i] + } + + return s } // After returns the substring after the first occurrence of a specified string in the source string. // Play: https://go.dev/play/p/RbCOQqCDA7m func After(s, char string) string { - i := strings.Index(s, char) - - if s == "" || char == "" || i == -1 { + if char == "" { return s } - return s[i+len(char):] + if i := strings.Index(s, char); i >= 0 { + return s[i+len(char):] + } + + return s } // AfterLast returns the substring after the last occurrence of a specified string in the source string. // Play: https://go.dev/play/p/1TegARrb8Yn func AfterLast(s, char string) string { - i := strings.LastIndex(s, char) - - if s == "" || char == "" || i == -1 { + if char == "" { return s } - return s[i+len(char):] + if i := strings.LastIndex(s, char); i >= 0 { + return s[i+len(char):] + } + + return s } // IsString check if the value data type is string or not. @@ -213,20 +222,15 @@ func Wrap(str string, wrapWith string) string { // Unwrap a given string from anther string. will change source string. // Play: https://go.dev/play/p/Ec2q4BzCpG- func Unwrap(str string, wrapToken string) string { - if str == "" || wrapToken == "" { + if wrapToken == "" || !strings.HasPrefix(str, wrapToken) || !strings.HasSuffix(str, wrapToken) { return str } - firstIndex := strings.Index(str, wrapToken) - lastIndex := strings.LastIndex(str, wrapToken) - - if firstIndex == 0 && lastIndex > 0 && lastIndex <= len(str)-1 { - if len(wrapToken) <= lastIndex { - str = str[len(wrapToken):lastIndex] - } + if len(str) < 2*len(wrapToken) { + return str } - return str + return str[len(wrapToken) : len(str)-len(wrapToken)] } // SplitEx split a given string which can control the result slice contains empty string or not. @@ -286,22 +290,21 @@ func Substring(s string, offset int, length uint) string { size := len(rs) if offset < 0 { - offset = size + offset - if offset < 0 { - offset = 0 - } + offset += size + } + if offset < 0 { + offset = 0 } if offset > size { return "" } - if length > uint(size)-uint(offset) { - length = uint(size - offset) + end := offset + int(length) + if end > size { + end = size } - str := string(rs[offset : offset+int(length)]) - - return strings.Replace(str, "\x00", "", -1) + return strings.ReplaceAll(string(rs[offset:end]), "\x00", "") } // SplitWords splits a string into words, word only contains alphabetic characters. diff --git a/strutil/string_internal.go b/strutil/string_internal.go index bce6f76..dd5578d 100644 --- a/strutil/string_internal.go +++ b/strutil/string_internal.go @@ -1,6 +1,7 @@ package strutil import ( + "strings" "unicode" ) @@ -111,31 +112,27 @@ func padAtPosition(str string, length int, padStr string, position int) string { padStr = " " } - length = length - len(str) - startPadLen := 0 + totalPad := length - len(str) + startPad := 0 + if position == 0 { - startPadLen = length / 2 + startPad = totalPad / 2 } else if position == 1 { - startPadLen = length + startPad = totalPad + } else if position == 2 { + startPad = 0 } - endPadLen := length - startPadLen + endPad := totalPad - startPad - charLen := len(padStr) - leftPad := "" - cur := 0 - for cur < startPadLen { - leftPad += string(padStr[cur%charLen]) - cur++ + repeatPad := func(n int) string { + repeated := strings.Repeat(padStr, (n+len(padStr)-1)/len(padStr)) + return repeated[:n] } - cur = 0 - rightPad := "" - for cur < endPadLen { - rightPad += string(padStr[cur%charLen]) - cur++ - } + left := repeatPad(startPad) + right := repeatPad(endPad) - return leftPad + str + rightPad + return left + str + right } // isLetter checks r is a letter but not CJK character.