Skip to content
java
import cn.hutool.core.lang.hash.MurmurHash;
import cn.hutool.core.util.RandomUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * 用户邀请码生成
 *
 * @author knight
 */
@Slf4j
@RequiredArgsConstructor
public class UserInviteCodeGenerate {

    private static final String INVITE_CODE_KEY = "app:inviteCode:bitmap";

    private static final int CODE_LENGTH = 6;

    private final StringRedisTemplate stringRedisTemplate;

    private static final String WITHOUT_STR = "oO0lL1q9QpP";

    /**
     * 邀请码是否存在
     */
    public boolean exist(String inviteCode) {
        int hash = MurmurHash.hash32(inviteCode);
        return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().getBit(INVITE_CODE_KEY, hash & 0x3FFFFFFF));
    }

    public String next() {
        String inviteCode;
        boolean exists;
        int attempts = 0;

        // 检查邀请码是否已存在
        do {
            inviteCode = generateUserInviteCode();
            exists = exist(inviteCode);
            attempts++;
        } while (exists);

        if (attempts > 3) {
            log.warn("邀请码生成次数: {}", attempts);
        }

        int hash = MurmurHash.hash32(inviteCode);
        // 设置该邀请码为已使用
        stringRedisTemplate.opsForValue().setBit(INVITE_CODE_KEY, hash & 0x3FFFFFFF, true);
        return inviteCode;
    }

    private String generateUserInviteCode() {
        return RandomUtil.randomStringWithoutStr(CODE_LENGTH, WITHOUT_STR);
    }

}
为什么需要hash?

位图(Bitmap)不能直接存储字符串