新增6位全局邀请码工具
This commit is contained in:
parent
58b2290ced
commit
20bb1efcdc
@ -0,0 +1,124 @@
|
||||
package ink.wgink.util.verification.share;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ShareCodeUtil
|
||||
* @Description: 分享码,全局唯一,长度6位
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/5/2 11:58 上午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class ShareCodeUtil {
|
||||
|
||||
/**
|
||||
* 随机字符串
|
||||
*/
|
||||
private static final char[] CHARS = new char[]{'F', 'L', 'G', 'W', '5', 'X', 'C', '3',
|
||||
'9', 'Z', 'M', '6', '7', 'Y', 'R', 'T', '2', 'H', 'S', '8', 'D', 'V', 'E', 'J', '4', 'K',
|
||||
'Q', 'P', 'U', 'A', 'N', 'B'};
|
||||
|
||||
private final static int CHARS_LENGTH = 32;
|
||||
/**
|
||||
* 邀请码长度
|
||||
*/
|
||||
private final static int CODE_LENGTH = 6;
|
||||
/**
|
||||
* 随机数据
|
||||
*/
|
||||
private final static long SLAT = 1234561L;
|
||||
/**
|
||||
* PRIME1 与 CHARS 的长度 L互质,可保证 ( id * PRIME1) % L 在 [0,L)上均匀分布
|
||||
*/
|
||||
private final static int PRIME1 = 3;
|
||||
|
||||
/**
|
||||
* PRIME2 与 CODE_LENGTH 互质,可保证 ( index * PRIME2) % CODE_LENGTH 在 [0,CODE_LENGTH)上均匀分布
|
||||
*/
|
||||
private final static int PRIME2 = 11;
|
||||
|
||||
/**
|
||||
* 生成邀请码
|
||||
*
|
||||
* @param id 唯一的id主键
|
||||
* @return code
|
||||
*/
|
||||
public static String gen(Long id) {
|
||||
//补位
|
||||
id = id * PRIME1 + SLAT;
|
||||
//将 id 转换成32进制的值
|
||||
long[] b = new long[CODE_LENGTH];
|
||||
//32进制数
|
||||
b[0] = id;
|
||||
for (int i = 0; i < CODE_LENGTH - 1; i++) {
|
||||
b[i + 1] = b[i] / CHARS_LENGTH;
|
||||
//按位扩散
|
||||
b[i] = (b[i] + i * b[0]) % CHARS_LENGTH;
|
||||
}
|
||||
b[5] = (b[0] + b[1] + b[2] + b[3] + b[4]) * PRIME1 % CHARS_LENGTH;
|
||||
|
||||
//进行混淆
|
||||
long[] codeIndexArray = new long[CODE_LENGTH];
|
||||
for (int i = 0; i < CODE_LENGTH; i++) {
|
||||
codeIndexArray[i] = b[i * PRIME2 % CODE_LENGTH];
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
Arrays.stream(codeIndexArray).boxed().map(Long::intValue).map(t -> CHARS[t]).forEach(buffer::append);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将邀请码解密成原来的id
|
||||
*
|
||||
* @param code 邀请码
|
||||
* @return id
|
||||
*/
|
||||
public static Long decode(String code) {
|
||||
if (code.length() != CODE_LENGTH) {
|
||||
return null;
|
||||
}
|
||||
//将字符还原成对应数字
|
||||
long[] a = new long[CODE_LENGTH];
|
||||
for (int i = 0; i < CODE_LENGTH; i++) {
|
||||
char c = code.charAt(i);
|
||||
int index = findIndex(c);
|
||||
if (index == -1) {
|
||||
//异常字符串
|
||||
return null;
|
||||
}
|
||||
a[i * PRIME2 % CODE_LENGTH] = index;
|
||||
}
|
||||
|
||||
long[] b = new long[CODE_LENGTH];
|
||||
for (int i = CODE_LENGTH - 2; i >= 0; i--) {
|
||||
b[i] = (a[i] - a[0] * i + CHARS_LENGTH * i) % CHARS_LENGTH;
|
||||
}
|
||||
|
||||
long res = 0;
|
||||
for (int i = CODE_LENGTH - 2; i >= 0; i--) {
|
||||
res += b[i];
|
||||
res *= (i > 0 ? CHARS_LENGTH : 1);
|
||||
}
|
||||
return (res - SLAT) / PRIME1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找对应字符的index
|
||||
*
|
||||
* @param c 字符
|
||||
* @return index
|
||||
*/
|
||||
private static int findIndex(char c) {
|
||||
for (int i = 0; i < CHARS_LENGTH; i++) {
|
||||
if (CHARS[i] == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user