新增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