业务需求,需要将2到36进制转十进制、十进制转2到36进制的功能,网上查找没有符合需求的,所以自己写了一个:
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Slf4j
public class RadixTransUtil {
final private static String charsNormalList = "0123456789ABCDEFGHIJKLMNOPQRSTUVWSYZ";
//用于排除Z和O的三十四进制
final private static String charsNoZOList = "0123456789ABCDEFGHIJKLMNPQRSTUVWSY";
/**
* 辅助方法,进制转换(支持2到36进制、长整型),tranType==0表示其它进制转换为十进制,tranType==1十进制转换为其它进制,tranType==2校验
*
* @param charsList
* @param numStr
* @param radix
* @param tranType
* @return
*/
private static String transRadix(String charsList, String numStr, int radix, int tranType) {
String result = null;
String signNo = ""; //正负数符号,空或“-”
//只支持2到36进制
if (1 >= radix || 36 < radix) {
return null;
}
//数值字符串不能为空,中间不能包括空白字符
if (null == numStr || 0 == numStr.trim().length() || numStr.trim().matches(".*\\s+.*")) {
return null;
}
//数值字符串转成单个字符数组
char[] nums = numStr.trim().toCharArray();
String numStrPos = numStr; //如果有负号,去掉负号
if ("-".equals(numStr.trim().substring(0, 1))) {
if (1 == numStr.trim().length()) {
return null;
} else {
signNo = "-";
nums = numStr.trim().substring(1).toCharArray();
numStrPos = numStr.trim().substring(1);
}
}
//对应进制字符集
String charsListCut = charsList.substring(0, radix);
if (0 == tranType || 2 == tranType) {
//其它进制转换为十进制时,校验数值字符串是否与相应字符集相符
for (char num : nums) {
if (-1 == charsListCut.indexOf(num)) {
log.error("表达式{}与进制字符集不匹配。", nums);
return null;
}
}
} else if (1 == tranType) {
//十进制转换为其它进制时,校验数值字符串是否与十进制字符集相符
String charsListCut10 = charsList.substring(0, 10);
for (char num : nums) {
if (-1 == charsListCut10.indexOf(num)) {
log.error("表达式{}与进制字符集不匹配。", nums);
return null;
}
}
}
//字符集转成单个字符数组
char[] chars = charsListCut.toCharArray();
Set<Map<String, Object>> hashSet = new HashSet<>();
try {
for (int i = 0; i <= chars.length - 1; i++) {
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("idx", i);
hashMap.put("num", chars[i]);
hashSet.add(hashMap);
}
} catch (Exception ex) {
log.error("数组转换Set集合失败。");
return null;
}
//转换成十进制
if (0 == tranType) {
Long numDecLong = 0L;
try {
//逐个字符计算
for (int i = 0; i <= nums.length - 1; i++) {
Long thPower = 1L;
for (int j = 1; j <= nums.length - 1 - i; j++) {
thPower = thPower * radix;
}
String num = String.valueOf(nums[i]);
//每个字符所对应的数值
Map<String, Object> numFind = hashSet.stream().filter(m -> num.equals(m.get("num").toString())).findFirst().orElse(null);
numDecLong = numDecLong + Long.parseLong(numFind.get("idx").toString()) * thPower;
}
result = signNo + numDecLong.toString();
} catch (Exception ex) {
log.error("进制转换失败。");
return null;
}
} else if (1 == tranType) {
try {
//要转换的结果同样是十进制,直接返回
if (10 == radix) {
return numStr.trim();
}
//要转换的结果同样不是十进制
Long numDecLong = Long.valueOf(numStrPos.trim()); //待转换数值(长整型)
String numTran = "";
Long quot = numDecLong; //商
Long rema = 0L; //余数
do {
if (quot < radix) {
rema = quot;
quot = 0L;
} else {
rema = quot % radix;
quot = (quot - quot % radix) / radix;
}
String idx = rema.toString().trim();
//每个字符所对应的数值
Map<String, Object> numFind = hashSet.stream().filter(m -> idx.equals(m.get("idx").toString())).findFirst().orElse(null);
numTran = numFind.get("num").toString() + numTran;
} while (quot > 0L);
result = signNo + numTran;
} catch (Exception ex) {
log.error("进制转换失败。");
return null;
}
} else if (2 == tranType) {
result = "TransEnable";
}
return result;
}
/**
* 其它进制转换为十进制(支持2到36进制、长整型)
*
* @param numStr
* @param radix
* @return
*/
public static String toDecLong(String numStr, int radix) {
String tranResult = transRadix(charsNormalList, numStr, radix, 0);
String result = tranResult == null ? "" : tranResult;
return result;
}
/**
* 十进制转换为其它进制(支持2到36进制、长整型)
*
* @param numStr
* @param radix
* @return
*/
public static String transFromDecLong(String numStr, int radix) {
String tranResult = transRadix(charsNormalList, numStr, radix, 1);
String result = tranResult == null ? "" : tranResult;
return result;
}
/**
* 判断是否可以转换为十进制
*
* @param numStr
* @param radix
* @return
*/
public static Boolean isDecLongEnable(String numStr, int radix) {
String check = transRadix(charsNormalList, numStr, radix, 2);
if (null == check) {
return false;
} else {
return true;
}
}
}
其中,用于排除Z和O的三十四进制的重新在写个方法调用就行了。