根据用户id生成唯一邀请码的方法中这句扩散算法原理是?

背景

有个需求是根据每个用户的id生成每个人唯一的邀请码,在网上查阅资料后发现了下边这个【进制法+扩散+混淆】算法,代码如下:

const (
    PRIME1 = 3 // 与字符集长度 62 互质
    PRIME2 = 5 // 与邀请码长度 6 互质
    SALT   = 123456789    // 随意取一个数值
)

// GetInvCodeByUIDUniqueNew 获取指定长度的邀请码。
func GetInvCodeByUIDUniqueNew(uid uint64, l int) string {
    // 放大 + 加盐。
    uid = uid*PRIME1 + SALT

    var code []rune
    slIdx := make([]byte, l)

    // 扩散。
    for i := 0; i < l; i++ {
        slIdx[i] = byte(uid % uint64(len(AlphanumericSet)))                   // 获取 62 进制的每一位值
        slIdx[i] = (slIdx[i] + byte(i)*slIdx[0]) % byte(len(AlphanumericSet)) // 其他位与个位加和再取余(让个位的变化影响到所有位)
        uid = uid / uint64(len(AlphanumericSet))                              // 相当于右移一位(62进制)
    }

    // 混淆。
    for i := 0; i < l; i++ {
        idx := (byte(i) * PRIME2) % byte(l)
        code = append(code, AlphanumericSet[slIdx[idx]])
    }
    return string(code)
}

// 示例
fmt.Println(GetInvCodeByUID(100000000, 6)) // d3ihcF
fmt.Println(GetInvCodeByUID(100000001, 6)) // giuqiI
fmt.Println(GetInvCodeByUID(100000002, 6)) // jxGzoL

问题

其中对这一句不太理解是什么原理,这是如何保证计算后所有的邀请码直接不会重的呢?

slIdx[i] = (slIdx[i] + byte(i)*slIdx[0]) % byte(len(AlphanumericSet)) // 其他位与个位加和再取余(让个位的变化影响到所有位)

自己实现脚本小批量测试后发现确实没有重复,但是这句不理解,是什么原理?

参考链接: https://blog.csdn.net/K346K34...

阅读 3.4k
1 个回答

https://hashids.org/

这个我感觉更好. 有初始iv, 可编码, 可解码.

描述里的长度为6, 结果空间就那么大, 肯定会重复的.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题