美文网首页
[code snippet]生成邀请码

[code snippet]生成邀请码

作者: 顾慎为 | 来源:发表于2018-03-18 19:45 被阅读14次

    参考用 Python 生成随机的邀请码

    正如参考中所述,邀请码不仅要能够防止客户端伪造,还要方便服务端验证。

    我大体依据参考中的思路。略微不同的是,id和原始码并没有直接拼接,而是交叉。

    import random
    import string
    s_set = string.ascii_letters + string.digits
    raw_code_len = 8
    
    
    class Code(models.Model):
        raw_code = fields.Char(string=u'原始码', index=True)
    
        @property
        def code(self):
            id_str = '{:0>8x}'.format(self.id)  # 转换为16进制,并用0填充至8位,故最大值为16**8 - 1
            return ''.join(''.join(i) for i in zip(id_str, self.raw_code))  # 在id的每个数字后填充随机字符,构成最终的码
    
        def check_code(self, code):
            id_str = code[::2]
            raw_code = code[1::2]
            try:
                int(id_str, 16)
            except ValueError, e:
                return False
            c = self.sudo().browse(int(id_str, 16))
            if c.exists() and c.raw_code == raw_code:
                return c
            else:
                return False
    
        @classmethod
        def generate_raw_code(cls):
            return ''.join(random.choice(s_set) for i in range(raw_code_len))
        
        def create(self, vals):
            c = super(Code, self).create(vals)
            c.raw_code = c.generate_raw_code()
            return c
    

    如果我的计算没错的话,这个最多可以产生近43亿个邀请码。

    另外,''.join(''.join(i) for i in zip(id_str, self.raw_code))可以改进。

    In [2]: from itertools import chain
    In [3]: id_str = '123'
    In [4]: raw_code = 'abc'
    
    In [5]: zip(id_str, raw_code)
    Out[5]: [('1', 'a'), ('2', 'b'), ('3', 'c')]
    
    In [8]: list(chain(*zip(id_str, raw_code)))
    Out[8]: ['1', 'a', '2', 'b', '3', 'c']
    
    In [11]: list(chain.from_iterable(zip(id_str, raw_code)))
    Out[11]: ['1', 'a', '2', 'b', '3', 'c']
    

    所以可以简化为:

    In [13]: ''.join(chain.from_iterable(zip(id_str, raw_code)))
    Out[13]: '1a2b3c'
    
    In [14]: ''.join(chain(*zip(id_str, raw_code)))
    Out[14]: '1a2b3c'
    

    也算是又一次学习了itertools.chain。(苦笑)

    如果用协程:

    In [3]: def fff():
       ...:     for i in zip(id_str, raw_code):
       ...:         yield from i
    In [6]: list(fff())
    Out[6]: ['1', 'a', '2', 'b', '3', 'c']
    

    当然,推荐使用 chain,其使用C实现,效率更高。

    相关文章

      网友评论

          本文标题:[code snippet]生成邀请码

          本文链接:https://www.haomeiwen.com/subject/exhyqftx.html