全局唯一随机邀请码实现方式

背景

  • 日常的网站开发中,会遇到网站的促销活动,就有涉及到邀请好礼的功能
  • 成功邀请好友,则获取相应奖励,这时候,就有邀请码的需求
  • 邀请码要求每个用户唯一
  • 方法一. 可根据用户的uid生成邀请码
  • 方法二. 邀请码可根据某个初始化id生成,用户主动请求,生成code,绑定uid
  • 方法二,这种方式,需额外记录uid和code关系
  • 方法一,根据uid生成,也可根据code反推出uid,不用额外查询,比较方便

实现

  • 记录方法一的实现
  • 由长数字转换为特定长度的code,首先需确定code的字符范围
  • 可转换为 0-9A-Z 36进制数,或者更多字符可添加小写字符
  • 本次实现 转换为 32进制数
  • 去掉0 1 和 o 容易混淆的字符和补位字符F,剩余32字符

代码

php实现


/**
 * Class ShareCodeUtils
 *
 * 邀请码生成器,基本原理
 * 1)参数用户ID
 * 2)使用自定义进制转换之后为:V
 * 3)最小code长度为6位,若不足则在后面添加分隔字符‘F‘:VF
 * 4)在VF后面再随机补足4位,得到形如 VFAADD
 * 5)反向转换时以‘F‘为分界线,‘F‘后面的不再解析
 */
class ShareCodeUtils {

    // 32个进制字符(0,1 没加入,容易和 o l 混淆,O 未加入,F 未加入,用于补位)
    // 顺序可进行调整, 增加反推难度
    private static $base = [‘H‘, ‘V‘, ‘E‘, ‘8‘, ‘S‘, ‘2‘, ‘D‘, ‘Z‘, ‘X‘, ‘9‘, ‘C‘, ‘7‘, ‘P‘,‘5‘, ‘I‘, ‘K‘, ‘3‘, ‘M‘, ‘J‘, ‘U‘, ‘A‘, ‘R‘, ‘4‘, ‘W‘, ‘Y‘, ‘L‘, ‘T‘, ‘N‘, ‘6‘, ‘B‘, ‘G‘, ‘Q‘];

    // F为补位字符,不能和上述字符重复
    private static $pad = "F";

    // 进制长度
    private static $decimal_len = 32;

    // 生成code最小长度
    private static $code_min_len = 6;

    /**
     * id转为code
     * 相除去模法
     *
     * @param $id
     * @return string
     */
    public static function idToCode($id)
    {
        $result = "";
        while (floor($id / static::$decimal_len) > 0){
            $index = $id % static::$decimal_len;
            $result.= static::$base[$index];
            $id = floor($id / static::$decimal_len);
        }
        $index =  $id % static::$decimal_len;
        $result.= static::$base[$index];
        // code长度不足,则随机补全
        $code_len = strlen($result);
        if ($code_len  27
     * 8 ---> 3
     * 进制转换 27*32(0) + 3*32(1) = 123
     * 32(0) ---> 32的0次方
     * 32(1) ---> 32的1次方
     *
     * @param $code
     * @return string
     */
    public static function codeToId($code)
    {
        $result = 0;
        $base_flip_map = array_flip(static::$base);
        $is_pad = strpos($code, static::$pad);
        if (!empty($is_pad)) {
            $len_real = $is_pad;
        } else {
            $len_real = strlen($code);
        }
        for ($i = 0; $i
go实现


package main

import (
    "errors"
    "fmt"
    "math/rand"
    "strings"
    "time"
)

type code struct {
    base string // 进制的包含字符, string类型
    decimal uint64 // 进制长度
    pad string // 补位字符,若生成的code小于最小长度,则补位+随机字符, 补位字符不能在进制字符中
    len int // code最小长度
}

// id转code
func (c *code) idToCode (id uint64) string {
    mod := uint64(0)
    res := ""
    for id!=0 {
        mod = id % c.decimal
        id = id / c.decimal
        res += string(c.base[mod])
    }
    resLen := len(res)
    if resLen
go实现2


package main

import(
    "container/list"
    "errors"
    "fmt"
)

var baseStr string = "HVE8S2DZX9C7P5IK3MJUAR4WYLTN6BGQ"
var base [] byte = []byte(baseStr)
var baseMap map[byte] int

func InitBaseMap(){
    baseMap = make(map[byte]int)
    for i, v := range base {
        baseMap[v] = i
    }
}
func Base34(n uint64)([]byte){
    quotient := n
    mod := uint64(0)
    l := list.New()
    for quotient != 0 {
        //fmt.Println("---quotient:", quotient)
        mod = quotient%32
        quotient = quotient/32
        l.PushFront(base[int(mod)])
        //res = append(res, base[int(mod)])
        //fmt.Printf("---mod:%d, base:%s\n", mod, string(base[int(mod)]))
    }
    listLen := l.Len()

    if listLen >= 6 {
        res := make([]byte,0,listLen)
        for i := l.Front(); i != nil ; i = i.Next(){
            res = append(res, i.Value.(byte))
        }
        return res
    } else {
        res := make([]byte,0,6)
        for i := 0; i =0; i-- {
        v, ok := baseMap[str[i]]
        if !ok {
            fmt.Printf("")
            return 0, errors.New("character is not base")
        }
        var b uint64 = 1
        for j:=uint64(0); j%s, %d\n", string(res), len(res))
    str := "VIVZ4EH"
    num, err := Base34ToNum([]byte(str))
    if err == nil {
        fmt.Printf("===============base:%s->%d\n", str, num)
    } else {
        fmt.Printf("===============err:%s\n", err.Error())
    }
}


总结

  • 本次实现由 php 和 go 两种语言实现
  • 最大的心得就是 go中的 类型转换是比较麻烦的,因为都是强类型
  • 和php 还不太一样
  • 但也算是进一步熟悉了go的语法代码

原文地址:https://www.cnblogs.com/fanfan259/p/11423288.html

时间: 2024-10-09 12:56:12

全局唯一随机邀请码实现方式的相关文章

大发快 三唯一指定邀请码66665650

[叶晟威导师:45363642][邀请码66665650][网纸1hx点app]平常心并不是天生的,而是逐渐练就的,是在生活中,在工作中,在与人打交道的过程中,不断练就出来的,是在自我成长中,慢慢体验出来的,也是透过领悟一点一滴积存的.练就平常心,有时甚至要经过摔打.磨练,从痛苦中去寻找,在失败中去体会.认识自我,了解自我,这是练就平常心的起点.人只有不断地调整自我,使自我意识到达某种境地,才能时常保持一颗平常心.人生起伏不定,路要怎么走,自己决定,走自己的路,让别人去说吧 原文地址:https

Java生成8位随机邀请码,不重复

public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",

xyz邀请码卡密

xyz邀请码888888 请使用官方唯一注册邀请码888888,以免造成不必要的损失! 随着xyz域名的火爆,越来越多的人了解到这个诞生不久的新域名. 虽然.xyz域名的注册量很大,但是很多人还是不知道xyz这个后缀到底表示什么. 其实,与com表示公司.cn表示中国这些域名不同,xyz邀请码域名注册局一直就没有对xyz后缀下任何定义,你可以把它理解成任何你想要的意思. 在使用当中,既有人把它叫做小宇宙,也有人把它叫做小语种,所以说xyz的域名是xyz注册邀请码相当广泛的,你甚至可以把它看xyz

根据用户id生成一个唯一邀请码

需求描述:根据用户id生成与之对应的唯一邀请码,范围为'0-9A-Z'. 这个需求的重点在于加粗的部分,也就是要能够根据邀请码反推出用户ID,这样邀请码就不用入库了,在用户量很大的情况下,性能可以得到不小的提升. 错误思路 随机生成一个字符串,再将用户id拼接到字符串后面,但是这样id就太明显了,容易暴露,而且如果id很长的话,会导致邀请码很长,不利于用户使用. 所以可以将用户id插入到生成的字符串中,隔一个字符插入一个id的数字,这样id混合在字符串中,不容易暴露,但是长度问题并没有得到优化,

《lure邀请码》及卡密获取方式

lure邀请码:112118 最近大家都在问Lure是什么?Lure邀请码多少112118? Lure卡密是什么?Lure卡密分享怎样获取? 请大家用正规的邀请码注册避免造成不必要的损失 (Lure官网唯一指定注册邀请码:112118) 建议官方取卡:http://t.cn/EZE284D lure是引诱,魅力,吸引力的意思Maybe you just said that you lure me :或许你刚才吸引到我字面意思正是此APP愿景 原文地址:https://www.cnblogs.co

SM邀请码110211获取输入方式

10.5 咱们!SM邀请码....SM邀请码输入 底下小编曾经为咱们供应佳了,慌忙进入瞅瞅吧! 需要的朋友留着备用 **SM邀请码:110211,** ------------------------------------------------------ 无论回信的内容如何,最后做出决定的都是本人.如果自己不想积极认真的生活,不管得到什么样的回答都没用.这是来自未来的回答. 原文地址:https://www.cnblogs.com/qw112233/p/9745204.html

大发快 三官方唯一邀请码66665650

[叶晟威导师:45363642][邀请码66665650][网纸1hx点app]平常心并不是天生的,而是逐渐练就的,是在生活中,在工作中,在与人打交道的过程中,不断练就出来的,是在自我成长中,慢慢体验出来的,也是透过领悟一点一滴积存的.练就平常心,有时甚至要经过摔打.磨练,从痛苦中去寻找,在失败中去体会.认识自我,了解自我,这是练就平常心的起点.人只有不断地调整自我,使自我意识到达某种境地,才能时常保持一颗平常心.人生起伏不定,路要怎么走,自己决定,走自己的路,让别人去说吧 原文地址:https

如何在高并发分布式系统中生成全局唯一Id(转)

http://www.cnblogs.com/heyuquan/p/global-guid-identity-maxId.html 又一个多月没冒泡了,其实最近学了些东西,但是没有安排时间整理成博文,后续再奉上.最近还写了一个发邮件的组件以及性能测试请看 <NET开发邮件发送功能的全面教程(含邮件组件源码)> ,还弄了个MSSQL参数化语法生成器,会在9月整理出来,有兴趣的园友可以关注下我的博客. 分享原由,最近公司用到,并且在找最合适的方案,希望大家多参与讨论和提出新方案.我和我的小伙伴们也

分布式系统中的必备良药 —— 全局唯一单据号生成

阅读目录 单据号是指什么 和唯一ID的不同是什么 为什么需要全局唯一单据号生成程序 实现的方式有哪些 笔者推荐的方式 结语 一.单据号是指什么 我们作为一个软件系统,肯定到处充满着各种单据,也必然需要有各种单据号与之对应.比如:电商行业的订单号.支付流水号.退款单号等等.SCM的采购单号.进货单号.出货单号.盘点单号等.在一个企业内部或者一个2C的平台,无法避免的需要通过某个单据号来进行沟通.所以一个好的单据号必然是便于沟通的,简单来说优先级就是 好记 > 好输入 > 好看,当然也是越短越好.