We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
某些App上有新用户邀请机制,新用户注册的时候输入邀请码后注册 后台会有优惠发放。
此场景下要求生成的邀请码是全局唯一的,即每个用户对应的邀请码都是唯一。
我们可以转换一下思路:每个用户都有唯一的uid,可以将uid通过某种算法生成邀请码。
/** * @author Ricky Fung */ @Service public class InvitationCodeService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final char[] dict = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; private static final int DICT_BIT_LENGTH = 5; private static final int DICT_MASK = (1 << DICT_BIT_LENGTH) - 1; /** * 纪元, 2018-08-01 00:00:00 */ private static final long epoch = new DateTime(2018, 8, 1, 0, 0, 0).getMillis(); /** * 时间戳位数 */ private static final int TIMESTAMP_BIT_LENGTH = 34; private static final long TIMESTAMP_MASK = (1L << TIMESTAMP_BIT_LENGTH) - 1; /** * 随机数 */ private static final int RANDOM_BIT_LENGTH = 3; private static final long RANDOM_MASK = (1L << RANDOM_BIT_LENGTH) - 1; /** * 随机数左移位数 */ private static final int RANDOM_LEFT_SHIFT_BITS = TIMESTAMP_BIT_LENGTH; /** * userId 左移位数 */ private static final int USER_LEFT_SHIFT_BITS = TIMESTAMP_BIT_LENGTH + RANDOM_BIT_LENGTH; /** * 所能支持的最大user_id */ private static final long MAX_USER_ID = (1L << (63 - USER_LEFT_SHIFT_BITS)) - 1; private static final int CODE_LENGTH = 13; /** * 不足则填充 零 */ private static final char PADDING_CHAR = '0'; /** * 生成招财码 * @param userId * @return */ public String genCode(long userId) { String code = getUniqueCode(userId); return padding(code, PADDING_CHAR, CODE_LENGTH); } public String getUniqueCode(long userId) { //1.得到一个long值 long num = getUniqueNum(userId).getUid(); //2.转换为字符串 StringBuilder sb = new StringBuilder(CODE_LENGTH); while (num != 0) { int i = (int) (num & DICT_MASK); sb.append(dict[i]); num = num >> DICT_BIT_LENGTH; } StringBuilder rs = sb.reverse(); return rs.toString(); } /** * 产生一个64bit的正整数 * @param userId * @return */ public FortuneUidVO getUniqueNum(long userId) { //bugfix: 修复超出范围后死循环导致OOM if (userId> MAX_USER_ID) { throw new IllegalArgumentException(String.format("userId:%s 超出最大id: %s范围了", userId, MAX_USER_ID)); } // long millis = System.currentTimeMillis(); long thread = Thread.currentThread().getId(); // long uid = (userId << USER_LEFT_SHIFT_BITS | ((thread & RANDOM_MASK) << RANDOM_LEFT_SHIFT_BITS) | ((millis - epoch) & TIMESTAMP_MASK)); return new FortuneUidVO(userId, thread, epoch, millis, uid); } private String padding(String str, char padding, int length) { if (str.length() >= length) { return str; } StringBuilder sb = new StringBuilder(length); if (str.length() < length) { //填充 int dist = length - str.length(); for (int i=0; i<dist; i++) { sb.append(padding); } } sb.append(str); return sb.toString(); } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
业务场景
某些App上有新用户邀请机制,新用户注册的时候输入邀请码后注册 后台会有优惠发放。
分析
此场景下要求生成的邀请码是全局唯一的,即每个用户对应的邀请码都是唯一。
我们可以转换一下思路:每个用户都有唯一的uid,可以将uid通过某种算法生成邀请码。
实现代码
The text was updated successfully, but these errors were encountered: