V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kisshere
V2EX  ›  程序员

不用数据库, PHP 每 10 分钟内生成一个恒定随机数,该怎样实现?

  •  2
     
  •   kisshere · 104 天前 · 4427 次点击
    这是一个创建于 104 天前的主题,其中的信息可能已经有所发展或是发生改变。

    api 请求一个 php 单文件,该 php 单文件(不调用数据库)每 10 分钟生成一个定值随机数,比如:

    8:00~8:10 请求该 php,只输出定值 23

    8:10~8:20 请求该 php,只输出定值 189

    8:20~8:30 请求该 php,只输出定值 3

    8:30~8:40 请求该 php,只输出定值 67

    ......

    这个该怎样实现?

    61 条回复    2021-08-25 09:02:50 +08:00
    luxcen
        1
    luxcen  
       104 天前   ❤️ 3
    if elseif else
    Switch ....
    dallaslu
        2
    dallaslu  
       104 天前
    8:00~8:10 请求该 php:base_convert(md5('8:00'), 16, 10) % MAX_VALUE

    8:10~8:20 请求该 php:base_convert(md5('8:10'), 16, 10) % MAX_VALUE
    yousabuk
        3
    yousabuk  
       104 天前 via iPhone
    说的再详细写才好看
    justrand
        4
    justrand  
       104 天前
    定值随机数 怎么理解?
    zoharSoul
        5
    zoharSoul  
       104 天前   ❤️ 26
    定值还叫随机数?

    五彩斑斓的黑是吧
    8bit
        6
    8bit  
       104 天前   ❤️ 1
    估计是不重复的随机数吧
    gfreezy
        7
    gfreezy  
       104 天前   ❤️ 5
    把 10 分钟当作随机数的种子,同一个 10 分钟内返回的都是同一个随机数
    hauzi
        8
    hauzi  
       104 天前
    直接用 cache 吧,10 分钟过期重新生成
    dinghmcn
        9
    dinghmcn  
       104 天前
    要第一次随机,其后直接使用该值?
    每次先检查当前时段随机值是否存在,不存在就取一个随机值并保存起来
    oott123
        10
    oott123  
       104 天前   ❤️ 1
    <?php
    define('MY_SUPER_SECRET_CONSTANT', 123456789);
    srand(intval(time() / 600) + MY_SUPER_SECRET_CONSTANT);
    echo rand(0, 500);
    oott123
        11
    oott123  
       104 天前   ❤️ 1
    以及我给的方法非常不安全(意味着该随机数可推测)。
    keepeye
        12
    keepeye  
       104 天前
    楼主的意思是,10 分钟内只生成一次随机数,多次请求返回缓存值。所以用缓存就行了啊,往 /tmp/目录下写个缓存文件,把时间、数值记录进去,每次读取,判断时间决定要不要重新生成
    boboliu
        13
    boboliu  
       104 天前 via Android   ❤️ 1
    你是不是在找:totp
    kisshere
        14
    kisshere  
    OP
       104 天前
    @justrand
    @zoharSoul 是根据时间段返回不同的随机数,时间段的最小区间长度是 10 分钟,该区间内,输出恒定数
    kisshere
        15
    kisshere  
    OP
       104 天前
    @keepeye 不往硬盘写文件,只用纯算法实现
    JKeita
        16
    JKeita  
       104 天前
    $t = time();
    $t = $t - $t%600;
    srand($t);
    $v = rand();
    echo $v;
    keepeye
        17
    keepeye  
       104 天前
    @kisshere 那你可以用 mt_srand 播种,种子就是时间拼成的整数
    pengtdyd
        18
    pengtdyd  
       104 天前
    大胆猜测一下,这个问题的背后必然有一个伞兵的产品经理
    hxnets
        19
    hxnets  
       104 天前
    恒定随机数???
    finull
        20
    finull  
       104 天前
    @kisshere @boboliu 提到的 TOTP 值得考虑
    JKeita
        21
    JKeita  
       104 天前
    srand 和 mt_srand 都是设置随机数种子,设置定值产生的随机数就一样了。
    InDom
        22
    InDom  
       104 天前
    https://imgur.com/M5Zdlve

    以整时间作为随机数种子,同 #11,非常不安全,随机数可推测,某种理论来说,这已经不是随机数了。
    xytest
        23
    xytest  
       103 天前
    生成一个 写到 redis 十分钟过期。
    RRRoger
        24
    RRRoger  
       103 天前
    生成随机数的目的就是不可预测。

    你可以根据时间特性写个简单的算法。

    比如在 8:00~8:10 你取 08:05 把所有的值(0,8,0,5)加起来得 13 然后通过 md5 算法, 从后往前取后面的整数位。

    至于整数位的个数,你可以用时间里数字 0 的个数。

    这样肉眼不可预测, 也能达到随机效果
    lxz6597863
        25
    lxz6597863  
       103 天前
    now := time.Now().Unix()
    fmt.Println(now - (now % 600))

    //600 秒 == 10 分钟
    boboliu
        26
    boboliu  
       103 天前
    boboliu
        27
    boboliu  
       103 天前
    ganbuliao
        28
    ganbuliao  
       103 天前
    那就很简单 8:00~8:10 就用 8:00 做这个加密算法的 value 不就行了 加密算法 就 什么随便的加减乘除一下 在截取一下就搞定了
    summerLast
        29
    summerLast  
       103 天前
    日期取 yyyyMMddHHm
    summerLast
        30
    summerLast  
       103 天前
    @summerLast 在复杂点 求个 hash
    summerLast
        31
    summerLast  
       103 天前
    @summerLast 在复杂点加盐 求个 hash
    wavingclear
        32
    wavingclear  
       103 天前
    抄一下网银实体数字密保、steam 手机验证器之类的离线随机数生成器的算法,他们几十秒更新一次你 10 分钟更新一次。
    binux
        33
    binux  
       103 天前 via Android
    随便找一个随机数算法,取第时间 offset/10min 个数就行了。
    bghtyu
        34
    bghtyu  
       103 天前 via Android
    就是 totp,Google 身份验证器那种
    eason1874
        35
    eason1874  
       103 天前
    不用自己实现,找个 TOTP 类,把间隔时间(默认是 30 秒或 60 秒)改成 600 秒就 OK 了
    neptuno
        36
    neptuno  
       103 天前
    是所有人都返回同一个随机数还是每个人随机数不同?所有人的话,生成一个随机数,缓存下来,后面的十分钟就返回这个随机数。每个人不同的话 totp
    feikeq
        37
    feikeq  
       103 天前
    你是不是要做动态令牌。。。。。我以前做过动态密码每天密码不一样的那种
    mingl0280
        38
    mingl0280  
       103 天前 via Android
    yyyyMMddHH 加上分钟取整加上 uid 哈希。totp 啊……
    Lemeng
        39
    Lemeng  
       103 天前
    需求写的不是特别清楚
    fuxkcsdn
        40
    fuxkcsdn  
       103 天前 via iPhone
    rsa 加密当前时间戳,保证恒定,保证随机

    bcmod(bcpow(time(), $e), $n)

    其中的 e 和 n 参数定义见
    https://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html

    https://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
    fuxkcsdn
        41
    fuxkcsdn  
       103 天前 via iPhone
    p.s.不要试图用 bcmath 拓展进行解密,超级慢。要解密的话用 gmp 拓展(只是相对 bcmath 快而已,数值大的话,解密也是慢)
    tabris17
        42
    tabris17  
       103 天前
    return (int)(time() / 10)
    bixchen
        43
    bixchen  
       103 天前
    单文件,反正都上服务器了。弄个 redis ttl 10min 是否存在,存在 return 不存在 create 然后 return
    imluvian
        44
    imluvian  
       103 天前 via Android
    楼主你这是想抽奖作弊啊?
    Coder89757
        45
    Coder89757  
       103 天前
    面试题请自己做,谢谢。。。
    Juszoe
        46
    Juszoe  
       103 天前
    每十分钟生成一个新的随机数,保存到全局变量里。
    建议楼主描述清楚需求,不然又成一个 X-Y problem
    shellus
        47
    shellus  
       103 天前
    其实你就是想生成一个动态的加密串,防止前端的加密串被拿去一直用。
    所以每 10 分钟这个加密串就禁用了。前端必须重新获取,是吧?
    不要重复造轮子了,这就是 JWT Auth
    Hardrain
        48
    Hardrain  
       103 天前
    时间戳 /600 作为 random seed?
    crab
        49
    crab  
       103 天前
    对时间间隔取余来固定种子数值
    yogogo
        50
    yogogo  
       103 天前   ❤️ 1
    不要碰灰产
    w3cll
        51
    w3cll  
       103 天前
    @yogogo 看来你有故事
    RRyo
        52
    RRyo  
       103 天前 via iPhone
    时间戳除你需要的间隔,做种子生成随机数,更工程化的可以参考 2FA 的那套东西,很多现成的库
    EscYezi
        53
    EscYezi  
       103 天前 via iPhone
    具体场景是怎么样的?
    yuzo555
        54
    yuzo555  
       103 天前
    用 hash 算法,比如 md5,原文为 intval(time() / 600) 加上一个很长的盐值,然后取十六进制格式的最后几位(具体几位取决于你想要的数字大小范围),然后转为十进制数。
    hefish
        55
    hefish  
       103 天前
    难得大家如此热情,我觉着这个需求莫名其妙,非常奇葩。 没有责怪 LZ 的意思,纯粹觉着需求奇葩。
    huskyui
        56
    huskyui  
       103 天前
    每天凌晨,可以预先生成一个满足数量的数组,然后打乱.根据时间点
    GeruzoniAnsasu
        57
    GeruzoniAnsasu  
       103 天前
    @zoharSoul

    鉴于本楼 lz 的问题已经得到解答了,歪个题,看看这算不算「五彩斑斓的黑」


    gitdoit
        58
    gitdoit  
       103 天前
    题目半天没读明白,还有这么多人回答, 我觉得我脑子有问题
    zjsxwc
        59
    zjsxwc  
       103 天前
    如果不能用数据库等存储(文件系统也算数据库)的话,

    每 10 秒恒定就说明你这个随机数是由你当前时间确定的,于是你这个随机根本就不是随机数!

    如果不是随机数,那么解决楼主需求的办法确实只有用 rsa 非对称加密办法了,最多就是密钥每天换一个新的。
    pckillers
        60
    pckillers  
       102 天前
    @zjsxwc 把年月日也加进判断不就得了。 日期 + 时间(精确到 10 分钟) + 字符 做个 MD5 再随便想个公式变回数字。 也看起来差不多像随机数了。
    raysonlu
        61
    raysonlu  
       102 天前
    就题目看,明显就 if else 完事,但感觉明显就是题目需求都没有说清楚
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2048 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 02:52 · PVG 10:52 · LAX 18:52 · JFK 21:52
    ♥ Do have faith in what you're doing.