本工具类为通过对 数字类型的ID 生成字符串,且结果可逆向解密。实则为进制的转换,大家用的时候可以将 dataChar 中的顺序改一下,就能得到和别人不一样工具类结果。非常适合邀请码的场景
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RandomUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author yy
* @date 2020年9月14日
* @description 邀请码工具类
*
*/
public class InviteCodeUtil {
//27位备选 此顺序不可更改
private static char[] dataChar = new char[] {'h','t','s','3','2','5','w','u','p','q','b','y','7','e','c','r','x','6','n','k','8','d','v','f','j','m','4'};
private static char[] coverChar = new char[] {'9','a','z'};//补位字符
public static void main(String[] args) {
// TODO Auto-generated method stub
//打乱字符
// String rStr="";
// String dataStr = "2345678bcdefhjkmnpqrstuvwxy";
// char[] chars = dataStr.toCharArray();
// List<String> l = new ArrayList<>();
// for (int i = 0; i < chars.length; i++) {
// l.add(chars[i]+"");
// }
// while (l.size()>0) {
// int i=RandomUtils.nextInt(0, l.size());
// rStr+="'"+l.get(i)+"',";
// l.remove(i);
// }
// System.out.println(rStr);
System.out.println(encode(6, 1));
System.out.println(encode(6, 100));
System.out.println(encode(6, 1000));
System.out.println(99999999+">>"+encode(6, 99999999)+">>"+decode("w42c5n"));
System.out.println(100000+">>"+encode(6, 100000)+">>"+decode("za5s2k"));
System.out.println(905625+">>"+encode(6, 905625)+">>"+decode("ztkhun"));
System.out.println(00001+">>"+encode(6, 00001)+">>"+decode("z999zt"));
System.out.println(157562548+">>"+encode(6, 157562548)+">>"+decode("b4eh2m"));
// long start = System.currentTimeMillis();
// for (int i = 0; i < 100000; i++) {
// System.out.println(157562548+">>"+encode(6, 157562548)+">>"+decode("b4eh2m"));
// }
// long end =System.currentTimeMillis();
// System.out.println(end-start);
}
/**
* @author yy
* @date 2020年9月14日
* @description 生成邀请码 6位数可表示约4亿
* @param minLen 最小长度
* @param id 唯一ID
* @return 不小于 minLen 的字符串
*/
public static String encode(int minLen,long id) {
//10进制 -->27进制
long div = id/27;//除数
List<Integer> mods = new ArrayList<>();//余数
mods.add((int)id%27);
while(div>0) {
mods.add((int)div%27);
div=div/27;
}
Collections.reverse(mods);//反转 获得高位->低位
StringBuilder sb = new StringBuilder();
mods.forEach(index->sb.append(dataChar[index]+""));
String returnStr = sb.toString();
//格式化
if(returnStr.length()<minLen) {
returnStr=getCoverChar(minLen)+returnStr;
returnStr=returnStr.substring(returnStr.length()-minLen, returnStr.length());
}
return returnStr;
}
/**
* @author yy
* @date 2020年9月14日
* @description 获取补位字符串
* @param minLen 长度
* @return
*/
private static String getCoverChar(int minLen) {
String rStr = "";
for (int i = 0; i < minLen; i++) {
rStr += coverChar[RandomUtils.nextInt(0, coverChar.length)];
}
return rStr;
}
/**
* @author yy
* @date 2020年9月14日
* @description 解码
* @param code 邀请码
* @return
*/
public static long decode(String code) {
//去除填充字符
for (int i = 0; i < coverChar.length; i++) {
code=code.replaceAll(coverChar[i]+"", "");
}
char[] codeChar = code.toCharArray();
long id=0L;//10进制结果
for (int i = 0; i < codeChar.length; i++) {
id+= Math.pow(27, codeChar.length-i-1) * ArrayUtils.indexOf(dataChar, codeChar[i]);
}
return id;
}
}