不用数据库, PHP 每 10 分钟内生成一个恒定随机数,该怎样实现? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
kisshere
V2EX    程序员

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

  kisshere 2021-08-23 10:19:23 +08:00 6204 次点击
这是一个创建于 1561 天前的主题,其中的信息可能已经有所发展或是发生改变。

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
y7E6IG8spV7TU8n7
    1
y7E6IG8spV7TU8n7  
   2021-08-23 10:21:22 +08:00   3
if elseif else
Switch ....
dallaslu
    2
dallaslu  
   2021-08-23 10:22:01 +08:00
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  
   2021-08-23 10:22:35 +08:00 via iPhone
说的再详细写才好看
yEhwG10ZJa83067x
    4
yEhwG10ZJa83067x  
   2021-08-23 10:27:32 +08:00
定值随机数 怎么理解?
zoharSoul
    5
zoharSoul  
   2021-08-23 10:28:49 +08:00   26
定值还叫随机数?

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

以整时间作为随机数种子,同 #11,非常不安全,随机数可推测,某种理论来说,这已经不是随机数了。
byteX
    23
byteX  
   2021-08-23 10:55:59 +08:00
生成一个 写到 redis 十分钟过期。
RRRoger
    24
RRRoger  
   2021-08-23 11:25:37 +08:00
生成随机数的目的就是不可预测。

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

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

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

这样肉眼不可预测, 也能达到随机效果
lxz6597863
    25
lxz6597863  
   2021-08-23 11:36:50 +08:00
now := time.Now().Unix()
fmt.Println(now - (now % 600))

//600 秒 == 10 分钟
boboliu
    26
boboliu  
   2021-08-23 12:19:43 +08:00
boboliu
    27
boboliu  
   2021-08-23 12:22:35 +08:00
ganbuliao
    28
ganbuliao  
   2021-08-23 12:26:16 +08:00
那就很简单 8:00~8:10 就用 8:00 做这个加密算法的 value 不就行了 加密算法 就 什么随便的加减乘除一下 在截取一下就搞定了
summerLast
    29
summerLast  
   2021-08-23 12:34:57 +08:00
日期取 yyyyMMddHHm
summerLast
    30
summerLast  
   2021-08-23 12:35:29 +08:00
@summerLast 在复杂点 求个 hash
summerLast
    31
summerLast  
   2021-08-23 12:36:03 +08:00
@summerLast 在复杂点加盐 求个 hash
wavingclear
    32
wavingclear  
   2021-08-23 12:46:23 +08:00
抄一下网银实体数字密保、steam 手机验证器之类的离线随机数生成器的算法,他们几十秒更新一次你 10 分钟更新一次。
binux
    33
binux  
   2021-08-23 12:54:45 +08:00 via Android
随便找一个随机数算法,取第时间 offset/10min 个数就行了。
bghtyu
    34
bghtyu  
   2021-08-23 12:59:06 +08:00 via Android
就是 totp,Google 身份验证器那种
eason1874
    35
eason1874  
   2021-08-23 13:30:05 +08:00
不用自己实现,找个 TOTP 类,把间隔时间(默认是 30 秒或 60 秒)改成 600 秒就 OK 了
neptuno
    36
neptuno  
   2021-08-23 13:52:41 +08:00
是所有人都返回同一个随机数还是每个人随机数不同?所有人的话,生成一个随机数,缓存下来,后面的十分钟就返回这个随机数。每个人不同的话 totp
feikeq
    37
feikeq  
   2021-08-23 14:16:38 +08:00
你是不是要做动态令牌。。。。。我以前做过动态密码每天密码不一样的那种
mingl0280
    38
mingl0280  
   2021-08-23 14:30:31 +08:00 via Android
yyyyMMddHH 加上分钟取整加上 uid 哈希。totp 啊……
Lemeng
    39
Lemeng  
   2021-08-23 15:35:50 +08:00
需求写的不是特别清楚
fuxkcsdn
    40
fuxkcsdn  
   2021-08-23 15:48:57 +08:00 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  
   2021-08-23 15:52:30 +08:00 via iPhone
p.s.不要试图用 bcmath 拓展进行解密,超级慢。要解密的话用 gmp 拓展(只是相对 bcmath 快而已,数值大的话,解密也是慢)
tabris17
    42
tabris17  
   2021-08-23 15:57:54 +08:00
return (int)(time() / 10)
bixchen
    43
bixchen  
   2021-08-23 16:12:16 +08:00
单文件,反正都上服务器了。弄个 redis ttl 10min 是否存在,存在 return 不存在 create 然后 return
imluvian
    44
imluvian  
   2021-08-23 16:26:11 +08:00 via Android
楼主你这是想抽奖作弊啊?
Coder89757
    45
Coder89757  
   2021-08-23 17:00:20 +08:00
面试题请自己做,谢谢。。。
Juszoe
    46
Juszoe  
   2021-08-23 17:10:34 +08:00
每十分钟生成一个新的随机数,保存到全局变量里。
建议楼主描述清楚需求,不然又成一个 X-Y problem
shellus
    47
shellus  
   2021-08-23 17:19:55 +08:00
其实你就是想生成一个动态的加密串,防止前端的加密串被拿去一直用。
所以每 10 分钟这个加密串就禁用了。前端必须重新获取,是吧?
不要重复造轮子了,这就是 JWT Auth
Hardrain
    48
Hardrain  
   2021-08-23 17:32:22 +08:00
时间戳 /600 作为 random seed?
crab
    49
crab  
   2021-08-23 17:42:35 +08:00
对时间间隔取余来固定种子数值
yogogo
    50
yogogo  
   2021-08-23 20:49:16 +08:00   1
不要碰灰产
w3cll
    51
w3cll  
   2021-08-23 21:54:21 +08:00
@yogogo 看来你有故事
RRyo
    52
RRyo  
   2021-08-23 22:28:31 +08:00 via iPhone
时间戳除你需要的间隔,做种子生成随机数,更工程化的可以参考 2FA 的那套东西,很多现成的库
EscYezi
    53
EscYezi  
   2021-08-23 22:34:41 +08:00 via iPhone
具体场景是怎么样的?
yuzo555
    54
yuzo555  
   2021-08-23 22:44:00 +08:00
用 hash 算法,比如 md5,原文为 intval(time() / 600) 加上一个很长的盐值,然后取十六进制格式的最后几位(具体几位取决于你想要的数字大小范围),然后转为十进制数。
hefish
    55
hefish  
   2021-08-23 23:32:51 +08:00
难得大家如此热情,我觉着这个需求莫名其妙,非常奇葩。 没有责怪 LZ 的意思,纯粹觉着需求奇葩。
huskyui
    56
huskyui  
   2021-08-24 00:15:43 +08:00
每天凌晨,可以预先生成一个满足数量的数组,然后打乱.根据时间点
GeruzoniAnsasu
    57
GeruzoniAnsasu  
   2021-08-24 07:51:34 +08:00
@zoharSoul

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


gitdoit
    58
gitdoit  
   2021-08-24 10:20:13 +08:00
题目半天没读明白,还有这么多人回答, 我觉得我脑子有问题
zjsxwc
    59
zjsxwc  
   2021-08-24 10:46:40 +08:00
如果不能用数据库等存储(文件系统也算数据库)的话,

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

如果不是随机数,那么解决楼主需求的办法确实只有用 rsa 非对称加密办法了,最多就是密钥每天换一个新的。
pckillers
    60
pckillers  
   2021-08-24 12:18:04 +08:00
@zjsxwc 把年月日也加进判断不就得了。 日期 + 时间(精确到 10 分钟) + 字符 做个 MD5 再随便想个公式变回数字。 也看起来差不多像随机数了。
raysonlu
    61
raysonlu  
   2021-08-25 09:02:49 +08:00
就题目看,明显就 if else 完事,但感觉明显就是题目需求都没有说清楚
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5292 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 29ms UTC 08:44 PVG 16:44 LAX 00:44 JFK 03:44
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86