實戰(zhàn)-全局唯一邀請碼功能實現(xiàn)
package com.secbro2.utils;
import java.util.Random;
/**
邀請碼生成器,基本原理:
1)入?yún)⒂脩鬒D:1
2)使用自定義進(jìn)制轉(zhuǎn)換之后為:V
3)轉(zhuǎn)換未字符串,并在后面添加'A':VA
4)在VA后面再隨機(jī)補(bǔ)足4位,得到:VAHKHE
5)反向轉(zhuǎn)換時以'A'為分界線,'A'后面的不再解析
-
@author zzs
*/
public class ShareCodeUtils {/**
- 自定義進(jìn)制(0,1沒有加入,容易與o,l混淆),數(shù)組順序可進(jìn)行調(diào)整增加反推難度,A用來補(bǔ)位因此此數(shù)組不包含A,共31個字符。
*/
private static final char[] BASE = new char[]{'H', 'V', 'E', '8', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P',
'5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'W', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'Q'};
/**
- A補(bǔ)位字符,不能與自定義重復(fù)
*/
private static final char SUFFIX_CHAR = 'A';
/**
- 進(jìn)制長度
*/
private static final int BIN_LEN = BASE.length;
/**
- 生成邀請碼最小長度
*/
private static final int CODE_LEN = 6;
/**
ID轉(zhuǎn)換為邀請碼
@param id
-
@return
*/
public static String idToCode(Long id) {
char[] buf = new char[BIN_LEN];
int charPos = BIN_LEN;// 當(dāng)id除以數(shù)組長度結(jié)果大于0,則進(jìn)行取模操作,并以取模的值作為數(shù)組的坐標(biāo)獲得對應(yīng)的字符
while (id / BIN_LEN > 0) {
int index = (int) (id % BIN_LEN);
buf[--charPos] = BASE[index];
id /= BIN_LEN;
}buf[--charPos] = BASE[(int) (id % BIN_LEN)];
// 將字符數(shù)組轉(zhuǎn)化為字符串
String result = new String(buf, charPos, BIN_LEN - charPos);// 長度不足指定長度則隨機(jī)補(bǔ)全
int len = result.length();
if (len < CODE_LEN) {
StringBuilder sb = new StringBuilder();
sb.append(SUFFIX_CHAR);
Random random = new Random();
// 去除SUFFIX_CHAR本身占位之后需要補(bǔ)齊的位數(shù)
for (int i = 0; i < CODE_LEN - len - 1; i++) {
sb.append(BASE[random.nextInt(BIN_LEN)]);
}result += sb.toString();}
return result;
}
/**
邀請碼解析出ID
基本操作思路恰好與idToCode反向操作。
@param code
-
@return
*/
public static Long codeToId(String code) {
char[] charArray = code.toCharArray();
long result = 0L;
for (int i = 0; i < charArray.length; i++) {
int index = 0;
for (int j = 0; j < BIN_LEN; j++) {
if (charArray[i] == BASE[j]) {
index = j;
break;
}
}if (charArray[i] == SUFFIX_CHAR) { break; } if (i > 0) { result = result * BIN_LEN + index; } else { result = index; }}
return result;
}
public static void main(String[] args) {
String code = idToCode(1L);
System.out.println(code);
System.out.println(codeToId(code));
} - 自定義進(jìn)制(0,1沒有加入,容易與o,l混淆),數(shù)組順序可進(jìn)行調(diào)整增加反推難度,A用來補(bǔ)位因此此數(shù)組不包含A,共31個字符。
}