com.anwen.mongo.toolkit.StringUtils Maven / Gradle / Ivy
package com.anwen.mongo.toolkit;
import com.anwen.mongo.constant.SqlOperationConstant;
import com.anwen.mongo.domain.MongoPlusConvertException;
import com.anwen.mongo.logging.Log;
import com.anwen.mongo.logging.LogFactory;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.joining;
public final class StringUtils {
static Log log = LogFactory.getLog(StringUtils.class);
/**
* 字符串 is
*/
public static final String IS = "is";
public static final int INDEX_NOT_FOUND = -1;
/**
* 下划线字符
*/
public static final char UNDERLINE = '_';
/**
* MP 内定义的 SQL 占位符表达式,匹配诸如 {0},{1},{2} ... 的形式
*/
public final static Pattern MP_SQL_PLACE_HOLDER = Pattern.compile("[{](?\\d+)}");
/**
* 验证字符串是否是数据库字段
*/
private static final Pattern P_IS_COLUMN = Pattern.compile("^\\w\\S*[\\w\\d]*$");
/**
* 是否为大写命名
*/
private static final Pattern CAPITAL_MODE = Pattern.compile("^[0-9A-Z/_]+$");
/**
* 字符串去除空白内容
*
* - \n 回车
- \t 水平制表符
- \s 空格
- \r 换行
*/
private static final Pattern REPLACE_BLANK = Pattern.compile("\\s*|\t|\r|\n");
/**
* 判断字符串中是否全是空白字符
*
* @param cs 需要判断的字符串
* @return 如果字符串序列是 null 或者全是空白,返回 true
*/
public static boolean isBlank(CharSequence cs) {
if (cs != null) {
int length = cs.length();
for (int i = 0; i < length; i++) {
if (!Character.isWhitespace(cs.charAt(i))) {
return false;
}
}
}
return true;
}
/**
* 对象转为字符串去除左右空格
*
* @param o 带转换对象
* @return String
*/
public static String toStringTrim(Object o) {
return String.valueOf(o).trim();
}
/**
* @see #isBlank(CharSequence)
*/
public static boolean isNotBlank(CharSequence cs) {
return !isBlank(cs);
}
public static boolean isEmpty(CharSequence cs) {
return cs == null || cs.length() == 0;
}
public static boolean isNotEmpty(CharSequence cs) {
return !isEmpty(cs);
}
/**
* @param str 字符串
* @return 是否不空
*/
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
public static String isNotBlankAndConvert(Object value){
try {
String str = String.valueOf(value);
if (isBlank(str)){
throw new MongoPlusConvertException("value is empty");
}
return str;
} catch (Exception e) {
log.warn("Conversion to String failed, reason for failure: {}",e.getMessage());
throw new MongoPlusConvertException("Conversion to String failed");
}
}
public static boolean hasLength(String str) {
return (str != null && !str.isEmpty());
}
public static boolean hasText(String str) {
return (str != null && !isBlank(str));
}
/**
* @param str 字符串
* @return 是否为空
*/
public static boolean isBlank(String str) {
if (str == null) {
return true;
}
if (str.equals("null")){
return true;
}
int len = str.length();
if (len == 0) {
return true;
}
for (int i = 0; i < len; i++) {
switch (str.charAt(i)) {
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
return false;
}
}
return true;
}
/**
* 首字母小写
* @param str 字符串
* @return String
*/
public static String firstCharToLowerCase(String str) {
return changeFirstCharCase(str, false);
}
/**
* 首字母大写
* @param str 字符串
* @return String
*/
public static String firstCharToUpperCase(String str) {
return changeFirstCharCase(str, true);
}
/**
* 更改字符串第一个字符的大小写
* @param str 字符串
* @param capitalize true大写 false小写
* @return 更改后的字符串
*/
private static String changeFirstCharCase(String str, boolean capitalize) {
if (str == null || str.isEmpty()) {
return str;
}
char baseChar = str.charAt(0);
char updatedChar;
if (capitalize) {
updatedChar = Character.toUpperCase(baseChar);
} else {
updatedChar = Character.toLowerCase(baseChar);
}
if (baseChar == updatedChar) {
return str;
} else {
char[] chars = str.toCharArray();
chars[0] = updatedChar;
return new String(chars);
}
}
/**
* 替换指定字符串的指定区间内字符为"*"
* 俗称:脱敏功能,后面其他功能,可以见:DesensitizedUtil(脱敏工具类)
*
*
* CharSequenceUtil.hide(null,*,*)=null
* CharSequenceUtil.hide("",0,*)=""
* CharSequenceUtil.hide("[email protected]",-1,4) ****[email protected]
* CharSequenceUtil.hide("[email protected]",2,3) ja*[email protected]
* CharSequenceUtil.hide("[email protected]",3,2) [email protected]
* CharSequenceUtil.hide("[email protected]",16,16) [email protected]
* CharSequenceUtil.hide("[email protected]",16,17) [email protected]
*
*
* @param str 字符串
* @param startInclude 开始位置(包含)
* @param endExclude 结束位置(不包含)
* @return 替换后的字符串
* @since 4.1.14
*/
public static String hide(CharSequence str, int startInclude, int endExclude) {
return replace(str, startInclude, endExclude, '*');
}
/**
* 重复某个字符
*
*
* CharSequenceUtil.repeat('e', 0) = ""
* CharSequenceUtil.repeat('e', 3) = "eee"
* CharSequenceUtil.repeat('e', -2) = ""
*
*
* @param c 被重复的字符
* @param count 重复的数目,如果小于等于0则返回""
* @return 重复字符字符串
*/
public static String repeat(char c, int count) {
if (count <= 0) {
return StringPool.EMPTY;
}
char[] result = new char[count];
Arrays.fill(result, c);
return new String(result);
}
/**
* 清理空白字符
*
* @param str 被清理的字符串
* @return 清理后的字符串
*/
public static String cleanBlank(CharSequence str) {
return filter(str, c -> !isBlankChar((int) c));
}
public static boolean isBlankChar(int c) {
return Character.isWhitespace(c)
|| Character.isSpaceChar(c)
|| c == '\ufeff'
|| c == '\u202a'
|| c == '\u0000'
// issue#I5UGSQ,Hangul Filler
|| c == '\u3164'
// Braille Pattern Blank
|| c == '\u2800'
// MONGOLIAN VOWEL SEPARATOR
|| c == '\u180e';
}
/**
* 过滤字符串
*
* @param str 字符串
* @param filter 过滤器
* @return 过滤后的字符串
* @since 5.4.0
*/
public static String filter(CharSequence str, final Function filter) {
if (str == null || filter == null) {
return str(str);
}
int len = str.length();
final StringBuilder sb = new StringBuilder(len);
char c;
for (int i = 0; i < len; i++) {
c = str.charAt(i);
if (filter.apply(c)) {
sb.append(c);
}
}
return sb.toString();
}
/**
* 截取分隔字符串之前的字符串,不包括分隔字符串
* 如果给定的字符串为空串(null或"")或者分隔字符串为null,返回原字符串
* 如果分隔字符串未找到,返回原字符串,举例如下:
*
*
* CharSequenceUtil.subBefore(null, *, false) = null
* CharSequenceUtil.subBefore("", *, false) = ""
* CharSequenceUtil.subBefore("abc", 'a', false) = ""
* CharSequenceUtil.subBefore("abcba", 'b', false) = "a"
* CharSequenceUtil.subBefore("abc", 'c', false) = "ab"
* CharSequenceUtil.subBefore("abc", 'd', false) = "abc"
*
*
* @param string 被查找的字符串
* @param separator 分隔字符串(不包括)
* @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
* @return 切割后的字符串
* @since 4.1.15
*/
public static String subBefore(CharSequence string, char separator, boolean isLastSeparator) {
if (isEmpty(string)) {
return null == string ? null : StringPool.EMPTY;
}
final String str = string.toString();
final int pos = isLastSeparator ? str.lastIndexOf(separator) : str.indexOf(separator);
if (INDEX_NOT_FOUND == pos) {
return str;
}
if (0 == pos) {
return StringPool.EMPTY;
}
return str.substring(0, pos);
}
/**
* 查找 src 里包含几个 target
* @param src 源字符串
* @param from 开始计数下标(包含)
* @param to 结束计数下标(不包含)
* @param targets 目标字符
* @return 个数
*/
public static int containCount(String src, int from, int to, char[] targets) {
int count = 0;
if (src != null) {
from = Math.max(from, 0);
to = Math.min(to, src.length());
for (int i = from; i < to; i ++) {
char c = src.charAt(i);
boolean contained = false;
for (char target : targets) {
if (c == target) {
contained = true;
break;
}
}
if (contained) {
count++;
}
}
}
return count;
}
/**
* 驼峰风格风格转连字符风格
* @param src 驼峰字符串
* @param hyphenation 连字符
* @return 连字符风格字符串
*/
public static String toHyphenation(String src, String hyphenation) {
StringBuilder sb = new StringBuilder(src);
int cnt = 0; // 插入连字符的个数
for(int i = 1; i < src.length(); i++){
if(Character.isUpperCase(src.charAt(i))){
sb.insert(i + cnt, hyphenation);
cnt += hyphenation.length();
}
}
return sb.toString().toLowerCase();
}
/**
* 驼峰风格风格转下划线风格
* @param src 驼峰字符串
* @return 下划风格字符串
*/
public static String toUnderline(String src) {
return toHyphenation(src, "_");
}
/**
* 快速判断 SQL 片段中是否包含某个列
* @param sql SQL 片段
* @param column 列名
* @return sql 中是否包含 column
*/
public static boolean sqlContains(String sql, String column) {
int cLen = column.length();
int idx = sql.indexOf(column);
while (idx >= 0) {
if (idx > 0) {
if (isSqlColumnChar(sql.charAt(idx - 1))) {
idx = sql.indexOf(column, idx + cLen);
continue;
}
}
int endIdx = idx + cLen;
if (endIdx < sql.length()) {
if (isSqlColumnChar(sql.charAt(endIdx))) {
idx = sql.indexOf(column, idx + cLen);
continue;
}
}
return true;
}
return false;
}
public static boolean isSqlColumnChar(char c) {
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_';
}
/**
* 指定范围内查找字符串
*
* @return 位置
* @since 3.2.1
*/
public static int indexOf(final CharSequence seq, final CharSequence searchSeq) {
if (seq == null || searchSeq == null) {
return INDEX_NOT_FOUND;
}
return indexOf(seq, searchSeq, 0);
}
public static int indexOf(final CharSequence cs, final CharSequence searchChar, final int start) {
return cs.toString().indexOf(searchChar.toString(), start);
}
/**
* 比较两个字符串是否相等,规则如下
*
* - str1和str2都为{@code null}
* - 忽略大小写使用{@link String#equalsIgnoreCase(String)}判断相等
* - 不忽略大小写使用{@link String#contentEquals(CharSequence)}判断相等
*
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
* @param ignoreCase 是否忽略大小写
* @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
* @since 3.2.0
*/
public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) {
if (null == str1) {
// 只有两个都为null才判断相等
return str2 == null;
}
if (null == str2) {
// 字符串2空,字符串1非空,直接false
return false;
}
if (ignoreCase) {
return str1.toString().equalsIgnoreCase(str2.toString());
} else {
return str1.toString().contentEquals(str2);
}
}
public static int countOf(String str, char target) {
if (str == null) {
return 0;
}
int count = 0;
int index = str.indexOf(target);
while (index >= 0) {
if (index >= str.length()) {
break;
}
index = str.indexOf(target, index + 1);
count++;
}
return count;
}
/**
* 判断字符串是不是驼峰命名
*
* 包含 '_' 不算
* 首字母大写的不算
*
* @param str 字符串
* @return 结果
*/
public static boolean isCamel(String str) {
return Character.isLowerCase(str.charAt(0)) && !str.contains(StringPool.UNDERSCORE);
}
/**
* 判断字符串是否符合数据库字段的命名
*
* @param str 字符串
* @return 判断结果
*/
public static boolean isNotColumnName(String str) {
return !P_IS_COLUMN.matcher(str).matches();
}
/**
* 获取真正的字段名
*
* @param column 字段名
* @return 字段名
*/
public static String getTargetColumn(String column) {
if (isNotColumnName(column)) {
return column.substring(1, column.length() - 1);
}
return column;
}
/**
* 字符串驼峰转下划线格式
*
* @param param 需要转换的字符串
* @return 转换好的字符串
*/
public static String camelToUnderline(String param) {
if (isBlank(param)) {
return StringPool.EMPTY;
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c) && i > 0) {
sb.append(UNDERLINE);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 字符串下划线转驼峰格式
*
* @param param 需要转换的字符串
* @return 转换好的字符串
*/
public static String underlineToCamel(String param) {
if (isBlank(param)) {
return StringPool.EMPTY;
}
String temp = param.toLowerCase();
int len = temp.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = temp.charAt(i);
if (c == UNDERLINE) {
if (++i < len) {
sb.append(Character.toUpperCase(temp.charAt(i)));
}
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 下划线转驼峰
* @author JiaChaoYang
* @date 2023/10/20 20:45
*/
public static String convertToCamelCase(String str) {
if (Objects.equals(str, SqlOperationConstant._ID)){
return str;
}
return Arrays.stream(str.split("_"))
.reduce((s1, s2) -> s1 + s2.substring(0, 1).toUpperCase() + s2.substring(1))
.orElse("");
}
/**
* 驼峰转下划线
* @author anwen
* @date 2024/6/27 下午11:47
*/
public static String convertCamelToUnderscore(String camelCaseString) {
if (camelCaseString == null || camelCaseString.isEmpty()) {
return camelCaseString;
}
return IntStream.range(0, camelCaseString.length())
.mapToObj(i -> {
char c = camelCaseString.charAt(i);
if (Character.isUpperCase(c)) {
return (i > 0 ? "_" : "") + Character.toLowerCase(c);
} else {
return String.valueOf(c);
}
})
.collect(Collectors.joining());
}
/**
* 正则表达式匹配
*
* @param regex 正则表达式字符串
* @param input 要匹配的字符串
* @return 如果 input 符合 regex 正则表达式格式, 返回true, 否则返回 false;
*/
public static boolean matches(String regex, String input) {
if (null == regex || null == input) {
return false;
}
return Pattern.matches(regex, input);
}
/**
* 替换指定字符串的指定区间内字符为固定字符
* 此方法使用{@link String#codePoints()}完成拆分替换
*
* @param str 字符串
* @param startInclude 开始位置(包含)
* @param endExclude 结束位置(不包含)
* @param replacedChar 被替换的字符
* @return 替换后的字符串
* @since 3.2.1
*/
public static String replace(CharSequence str, int startInclude, int endExclude, char replacedChar) {
if (isEmpty(str)) {
return str(str);
}
final String originalStr = str(str);
int[] strCodePoints = originalStr.codePoints().toArray();
final int strLength = strCodePoints.length;
if (startInclude > strLength) {
return originalStr;
}
if (endExclude > strLength) {
endExclude = strLength;
}
if (startInclude > endExclude) {
// 如果起始位置大于结束位置,不替换
return originalStr;
}
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < strLength; i++) {
if (i >= startInclude && i < endExclude) {
stringBuilder.append(replacedChar);
} else {
stringBuilder.append(new String(strCodePoints, i, 1));
}
}
return stringBuilder.toString();
}
/**
* {@link CharSequence} 转为字符串,null安全
*
* @param cs {@link CharSequence}
* @return 字符串
*/
public static String str(CharSequence cs) {
return null == cs ? null : cs.toString();
}
/**
* 获取SQL PARAMS字符串
*/
public static String sqlParam(Object obj) {
String repStr;
if (obj instanceof Collection) {
repStr = StringUtils.quotaMarkList((Collection>) obj);
} else {
repStr = StringUtils.quotaMark(obj);
}
return repStr;
}
/**
* 使用单引号包含字符串
*
* @param obj 原字符串
* @return 单引号包含的原字符串
*/
public static String quotaMark(Object obj) {
String srcStr = String.valueOf(obj);
if (obj instanceof CharSequence) {
// fix #79
return StringEscape.escapeString(srcStr);
}
return srcStr;
}
/**
* 使用单引号包含字符串
*
* @param coll 集合
* @return 单引号包含的原字符串的集合形式
*/
public static String quotaMarkList(Collection> coll) {
return coll.stream().map(StringUtils::quotaMark)
.collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET));
}
/**
* 拼接字符串第二个字符串第一个字母大写
*/
public static String concatCapitalize(String concatStr, final String str) {
if (isBlank(concatStr)) {
concatStr = StringPool.EMPTY;
}
if (str == null || str.isEmpty()) {
return str;
}
final char firstChar = str.charAt(0);
if (Character.isTitleCase(firstChar)) {
// already capitalized
return str;
}
return concatStr + Character.toTitleCase(firstChar) + str.substring(1);
}
/**
* 判断对象是否不为空
*
* @param object ignore
* @return ignore
*/
public static boolean checkValNotNull(Object object) {
if (object instanceof CharSequence) {
return isNotEmpty((CharSequence) object);
}
return object != null;
}
/**
* 判断对象是否为空
*
* @param object ignore
* @return ignore
*/
public static boolean checkValNull(Object object) {
return !checkValNotNull(object);
}
/**
* 包含大写字母
*
* @param word 待判断字符串
* @return ignore
*/
public static boolean containsUpperCase(String word) {
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (Character.isUpperCase(c)) {
return true;
}
}
return false;
}
/**
* 是否为大写命名
*
* @param word 待判断字符串
* @return ignore
*/
public static boolean isCapitalMode(String word) {
return null != word && CAPITAL_MODE.matcher(word).matches();
}
/**
* 是否为驼峰下划线混合命名
*
* @param word 待判断字符串
* @return ignore
*/
public static boolean isMixedMode(String word) {
return matches(".*[A-Z]+.*", word) && matches(".*[/_]+.*", word);
}
/**
* 判断是否以某个字符串结尾(区分大小写)
* Check if a String ends with a specified suffix.
*
* null
s are handled without exceptions. Two null
* references are considered to be equal. The comparison is case sensitive.
*
*
*
* StringUtils.endsWith(null, null) = true
* StringUtils.endsWith(null, "abcdef") = false
* StringUtils.endsWith("def", null) = false
* StringUtils.endsWith("def", "abcdef") = true
* StringUtils.endsWith("def", "ABCDEF") = false
*
*
*
* @param str the String to check, may be null
* @param suffix the suffix to find, may be null
* @return true
if the String ends with the suffix, case
* sensitive, or both null
* @see String#endsWith(String)
* @since 2.4
*/
public static boolean endsWith(String str, String suffix) {
return endsWith(str, suffix, false);
}
/**
* Check if a String ends with a specified suffix (optionally case
* insensitive).
*
* @param str the String to check, may be null
* @param suffix the suffix to find, may be null
* @param ignoreCase inidicates whether the compare should ignore case (case- * insensitive) or not.
* @return true
if the String starts with the prefix or both
* null
* @see String#endsWith(String)
*/
private static boolean endsWith(String str, String suffix, boolean ignoreCase) {
if (str == null || suffix == null) {
return (str == null && suffix == null);
}
if (suffix.length() > str.length()) {
return false;
}
int strOffset = str.length() - suffix.length();
return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
}
/**
* 是否为CharSequence类型
*
* @param clazz class
* @return true 为是 CharSequence 类型
*/
public static boolean isCharSequence(Class> clazz) {
return clazz != null && ClassTypeUtil.isTargetClass(CharSequence.class,clazz);
}
/**
* 前n个首字母小写,之后字符大小写的不变
*
* @param rawString 需要处理的字符串
* @param index 多少个字符(从左至右)
* @return ignore
*/
public static String prefixToLower(String rawString, int index) {
String field = rawString.substring(0, index).toLowerCase() +
rawString.substring(index);
return field;
}
/**
* 删除字符前缀之后,首字母小写,之后字符大小写的不变
* StringUtils.removePrefixAfterPrefixToLower( "isUser", 2 ) = user
* StringUtils.removePrefixAfterPrefixToLower( "isUserInfo", 2 ) = userInfo
*
* @param rawString 需要处理的字符串
* @param index 删除多少个字符(从左至右)
* @return ignore
*/
public static String removePrefixAfterPrefixToLower(String rawString, int index) {
return prefixToLower(rawString.substring(index), 1);
}
/**
* 驼峰转连字符
* StringUtils.camelToHyphen( "managerAdminUserService" ) = manager-admin-user-service
*
* @param input ignore
* @return 以'-'分隔
* @see document
*/
public static String camelToHyphen(String input) {
return wordsToHyphenCase(wordsAndHyphenAndCamelToConstantCase(input));
}
private static String wordsAndHyphenAndCamelToConstantCase(String input) {
StringBuilder buf = new StringBuilder();
char previousChar = ' ';
char[] chars = input.toCharArray();
for (char c : chars) {
boolean isUpperCaseAndPreviousIsLowerCase = (Character.isLowerCase(previousChar)) && (Character.isUpperCase(c));
boolean previousIsWhitespace = Character.isWhitespace(previousChar);
boolean lastOneIsNotUnderscore = (buf.length() > 0) && (buf.charAt(buf.length() - 1) != '_');
boolean isNotUnderscore = c != '_';
if (lastOneIsNotUnderscore && (isUpperCaseAndPreviousIsLowerCase || previousIsWhitespace)) {
buf.append(StringPool.UNDERSCORE);
} else if ((Character.isDigit(previousChar) && Character.isLetter(c))) {
buf.append(UNDERLINE);
}
if ((shouldReplace(c)) && (lastOneIsNotUnderscore)) {
buf.append(UNDERLINE);
} else if (!Character.isWhitespace(c) && (isNotUnderscore || lastOneIsNotUnderscore)) {
buf.append(Character.toUpperCase(c));
}
previousChar = c;
}
if (Character.isWhitespace(previousChar)) {
buf.append(StringPool.UNDERSCORE);
}
return buf.toString();
}
private static boolean shouldReplace(char c) {
return (c == '.') || (c == '_') || (c == '-');
}
private static String wordsToHyphenCase(String s) {
StringBuilder buf = new StringBuilder();
char lastChar = 'a';
for (char c : s.toCharArray()) {
if ((Character.isWhitespace(lastChar)) && (!Character.isWhitespace(c))
&& ('-' != c) && (buf.length() > 0)
&& (buf.charAt(buf.length() - 1) != '-')) {
buf.append(StringPool.DASH);
}
if ('_' == c) {
buf.append(StringPool.DASH);
} else if ('.' == c) {
buf.append(StringPool.DASH);
} else if (!Character.isWhitespace(c)) {
buf.append(Character.toLowerCase(c));
}
lastChar = c;
}
if (Character.isWhitespace(lastChar)) {
buf.append(StringPool.DASH);
}
return buf.toString();
}
/**
* 比较两个字符串,相同则返回true。字符串可为null
*
* 对字符串大小写敏感
*
*
* StringUtils.equals(null, null) = true
* StringUtils.equals(null, "abc") = false
* StringUtils.equals("abc", null) = false
* StringUtils.equals("abc", "abc") = true
* StringUtils.equals("abc", "ABC") = false
*
*
* @param cs1 第一个字符串, 可为 {@code null}
* @param cs2 第二个字符串, 可为 {@code null}
* @return {@code true} 如果两个字符串相同, 或者都为 {@code null}
* @see Object#equals(Object)
*/
public static boolean equals(final CharSequence cs1, final CharSequence cs2) {
if (cs1 == cs2) {
return true;
}
if (cs1 == null || cs2 == null) {
return false;
}
if (cs1.length() != cs2.length()) {
return false;
}
if (cs1 instanceof String && cs2 instanceof String) {
return cs1.equals(cs2);
}
// Step-wise comparison
final int length = cs1.length();
for (int i = 0; i < length; i++) {
if (cs1.charAt(i) != cs2.charAt(i)) {
return false;
}
}
return true;
}
/**
* 字符串转字节数组
* @param hex 字符串
* @return {@link byte[]}
* @author anwen
* @date 2024/6/30 上午12:21
*/
public static byte[] hexToBytes(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i+1), 16));
}
return data;
}
/**
* 将字节数组转为十六进制字符串
* @param hashBytes 字节
* @return {@link java.lang.String}
* @author anwen
* @date 2024/6/30 上午12:23
*/
public static String bytesToHex(byte[] hashBytes){
StringBuilder hexString = new StringBuilder();
for (byte hashByte : hashBytes) {
String hex = Integer.toHexString(0xff & hashByte);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}