zoukankan      html  css  js  c++  java
  • Redis调用lua生成验证码

    场景:

    ​ 通过微信公众号拿验证码在APP上绑定,为了防止重复,尝试使用reids-lua的方法实现此功能

    以下是 php 调用 redis.eval 方法传入的 lua 方法,当然这只是修改后的,保留了主要逻辑

    local time = 1542363164 // unix时间戳
    local code = redis.call('get',1)
    if (code) then 
        return code
    else 
    	local i = 0
        while(true) do 
            math.randomseed(time+i)
            code = math.random(100000,999999)
            if (1 == redis.call('setnx',1,code)) then 
            	return code
            end
        end
    end
    return 0
    

    乍一看没问题,但是要知道 redis 在创建 lua 环境的时候,第6步是这样的(具体为什么是这样的 https://redisbook.readthedocs.io/en/latest/feature/scripting.html#id2)

    用 Redis 自己定义的随机生成函数,替换 math 表原有的 math.random 函数和 math.randomseed 函数,新的函数具有这样的性质:每次执行 Lua 脚本时,除非显式地调用 math.randomseed ,否则 math.random 生成的伪随机数序列总是相同的。

    也就是说,如果不改变randomseed,random返回的序列会总是相同的,所以会拿到同样的值。

    这就需要考虑一个场景:

    ​ 一秒内有600个用户同时访问, randomseed 会一直增加到time+600,会把未来10分钟的时间戳都占用。一秒内请求越多,占用未来时间戳越多,循环时间就越长。

    ​ 就是一个秒数只能承载一个用户的验证码,想来想去,决定使用拼接的方式实现 math.randomseed(time .. i) 这样一个秒数可以实现承载更多。

  • 相关阅读:
    iOS开发——Xcode快捷键
    iOS开发——国际化支持Localizable.strings
    SQL 函数
    常用窗体表单布局
    Extjs grid combo
    怎么完全卸载sql2005?
    ExtJS文件上传
    ExtJS视频学习笔记
    ExtJS问题集——Menu的show()和showBy()函数是什么意思
    C# DataGridView操作
  • 原文地址:https://www.cnblogs.com/lisq/p/10011345.html
Copyright © 2011-2022 走看看