Notion 的随机漫步公式解析

Notion 的随机漫步公式解析

Feb 03 ·
9 分钟阅读

我在 Notion 上有一个和朋友们分享内容的 Workspace,我当时想设置一个随机漫步的模块在首页用以随机展示 10 个不同的内容,于是想到了根据随机数排序的方法,而要求则是自动生成随机数和随机数定时变化,在这些条件限制下很自然地就想到了时间戳,然后找到了这篇文章:

在notion中实现flomo随机漫步的效果

其中的方法解决了我的需求,具体步骤在这里就不重复写了,里面用到了一条很关键公式:

(((((timestamp(prop("Created time")) * 100011979) + 500067713) % 900066731) * ((((round(timestamp(now()) / 600000) * 600000) * 800067089) + 800068411) % 800053967)) + 900067309) % 900066571

这篇文章将会简单解析这条公式怎么运作。

公式分解

直接看公式有点乱,我先将它的书写优化一下:

为什么这个公式有效

线性同余方法(LCG )

把这个公式分解后,很容易看到公式的规律,这是 3 个 (A*X + B) % C 一样结构的公式组合,这个结构明显和伪随机数生成的其中一个经典方式线性同余方法(LCG) 有关。

Xn+1=(aXn+c)modmX_{n+1} = (a X_n + c) \mod m

以上是 LCG 的公式,这个方法保证了通过内容的时间戳生成随机 A 和 B 的值,这是前两次生成随机数。

多级混淆

公式里使用了多个 LCG 公式混合计算,主要是为了:

大质数的选择

2023 年我用过多个 AI 都无法讲明白这个问题,最近借助 DeepSeek 又重新解析了一遍。

公式中所有乘数(100011979800067089)和模数(900066731800053967900066571)均为大质数,推测原因:

模数和加法常数的选择

最后一步的模数是 900066571,而前面的加法常数是 900067309,比模数大一点,这样加上之后取模,可能会让数值分布更加均匀。

通常,在 (A * B) % m 形式的运算中,m 直接限制了输出范围,使得余数的分布可能受到 m 的影响,比如某些数字出现的频率更高。

但如果再加上一个 大于 m 的常数 C,即:(A * B + C) % m

由于 C 本身的取值不会影响 A * B 的结构(但会改变模运算的结果),可能会使某些原本较少出现的余数变得更常见,从而让结果的分布更均匀。

时间窗口

时间窗口的设计用于定时更新 B 的值,即使用当前时间除以十分钟再进行四舍五入,以计算当前时间靠近「第几个十分钟」,再乘以 10 分钟换算回时间戳格式。

注意公式里使用 6000000 是因为 Notion 的时间戳是毫秒级时间戳。

结果的排序

在最后一步,我们取用最终结果的正/倒序来进行随机漫步内容的展示,那么生成的随机数的的大小排序一定会变化吗?那是大概率的,不然也不会叫做随机数生成了,我们可以举很简单的例子验证一下:

初始计算
1. (7 * 3+3)%5 =4
2. (11 * 3+3)%5=1
3. (13 * 3+3)%5=2
更新 B 的值
4. (7 * 7+3)%5=2
5. (11 * 7+3)%5=0
6. (13 * 7+3)%5=4

可见以结果大小顺序排列的话,两次的顺序分别是:132 和 312。

其他疑问

创建时间相同导致随机数一样

由于从别的地方批量复制内容到 Database 中,以致于这批内容生成的随机数一样,在如何在 Notion 中实践 Zettelkasten 这篇文章的评论区提出了同样问题并给出了一个解决方案。

利用创建时间生成随机漫步的数值想法真的不错!

实际操作时我发现作为一个 creative user,我又遇到了问题。我的一部分笔记是从其他工作区复制汇总而得,这导致它们的创建时间都是一样的。在进一步调试的过程中,我发现由于Notion 页面的创建时间(以及最后编辑时间)仅精确到分,重复的概率还是不小的。

最后我的做法是把上述两个时间的 timestamp 值相加,希望多加一个变量能减少重复的概率。

自己回复自己~

在高人指点下(@SilentDepth 和 @niinjoy),将页面 ID 变为数字,替换原来公式里的timestamp 部分~

toNumber(replaceAll(id(), “[a-f]”, “0”))

修改刷新时间

修改公式中的 600000 数字,注意这个数字的单位是 ms。

能不能应用到其他地方

比如应用到飞书多维表格上,原理上应该可以,但未实践过。

参考链接

公式的原始来源大概是第一个链接。

编辑于 Apr 01