如果你用过 Discord 账号年龄查询工具,那你其实已经在使用 Snowflake 的能力了。
Discord Snowflake 是 Discord 给用户、服务器、频道、身份组、消息等对象使用的数字 ID 格式。它并不是随便生成的一串数字,而是带有时间信息的。
为什么 Discord 要用 Snowflake
Snowflake 让 Discord 可以在大规模分布式系统中生成唯一 ID,同时还能保留基本的时间顺序。
这使它非常适合:
- 排序新创建的对象
- 判断一个账号的大致年龄
- 追踪消息、频道、服务器是什么时候创建的
Snowflake 里编码了什么
一个 Discord Snowflake 通常包含:
- 时间戳
- 内部 worker 信息
- 内部 process 信息
- 序列号
其中最重要的是时间戳部分,因为这正是账号年龄工具的基础。
完整的 64 位结构可以拆成四段:前 42 位是从 Discord Epoch 开始累计的毫秒数,接着是 5 位 worker、5 位 process,最后 12 位是同一毫秒内的递增序号。后三段帮助 Discord 在分布式系统中生成不重复的 ID,但它们不是设备编号、IP 地址或地理位置。
为什么它可以反推出创建时间
Snowflake 的前 42 位代表从 Discord epoch 开始累计的毫秒数,而 Discord epoch 是 2015 年 1 月 1 日。
通过解码这个区段,工具就能计算出:
- 精确创建日期
- 账号大致年龄
- 不同对象是否在接近时间内创建
得到的是一个固定的 UTC 时刻。网站通常会按浏览器的本地时区显示,所以位于不同时区的两个人可能看到不同钟点,甚至看到相邻的两个日期。这只是显示方式不同,底层毫秒时间戳并没有变化。
逐步解码 Snowflake
解码创建时间的核心公式是:
timestamp_ms = (snowflake >> 22) + 14200704000001420070400000 是 Discord Epoch 对应的 Unix 毫秒值。右移 22 位会去掉 worker、process 和 increment 字段,只留下时间偏移量。
在 JavaScript 中不能先用普通 Number 保存 Discord ID。很多 ID 已经超过 Number.MAX_SAFE_INTEGER,转换后末尾数字可能被静默舍入,最终算出错误时间。应保留原始字符串并使用 BigInt:
const DISCORD_EPOCH = 1420070400000n;
function createdAtFromSnowflake(id) {
const timestamp = (BigInt(id) >> 22n) + DISCORD_EPOCH;
return new Date(Number(timestamp));
}只有提取出的毫秒时间戳才转换回 Number。正常日期范围内的毫秒值仍处于 JavaScript 的安全整数范围。如果 BigInt(id) 抛出错误,输入就不是干净的整数字符串,不应继续把它当作 Discord Snowflake。
完整计算示例
以 175928847299117063 为例:
- 把原始字符串转换成
BigInt。 - 右移 22 位,得到相对于 Discord Epoch 的毫秒偏移。
- 加上
1420070400000。 - 把结果转换成 ISO 日期。
最终时间是 2016-04-30T11:18:25.796Z,结尾的 Z 表示 UTC。这个示例的 worker、process 和 increment 分别是 1、0、7。这些数字能解释 ID 如何保持唯一,却不能告诉你账号来自哪里、使用什么设备,也不能证明谁正在控制这个账号。
Snowflake 的实际用途
常见用途包括:
- 识别刚注册的 spam 或 raid 账号
- 在审核流程中判断用户资历
- 推算服务器或频道创建时间
- 复盘社区事件时还原消息时间顺序
管理人员可以把账号年龄作为 spam 或 raid 排查的一个上下文信号,但不应该单独据此处罚用户。新账号不一定恶意,旧账号也不一定可信。更稳妥的判断需要结合服务器内可观察到的行为、消息内容和社区规则。
Snowflake 还能帮助定位“对象类型不匹配”。一个频道 ID 可能完全符合 Snowflake 格式并成功解码日期,但把它放进用户资料查询时不会返回头像或用户名。成功解码只说明数字结构有效,不说明它一定属于用户。
Snowflake 不能告诉你什么
也要避免夸大它的作用。
Discord ID 不能 直接暴露:
- 密码
- 邮箱
- 私聊内容
- 支付信息
- 私密服务器成员历史
它的价值主要在于时间推断和对象标识的一致性。
它同样不包含当前用户名、显示名称、头像、横幅、徽章或服务器成员关系。那些字段必须来自 Discord 的其他响应。这就是为什么账号年龄可以正常显示,而资料查询仍可能显示 Unknown User 或没有图片。
为什么它对 Discord 工具这么重要
Snowflake 是 Discord 工具有用的重要原因之一,因为即使拿不到完整资料字段,ID 本身也可能足以还原:
- 账号创建时间
- 服务器创建时间
- 消息创建时间
这种数据分层也有助于解释错误:本地时间解码成功,只能证明这个数字具有可用的 Snowflake 时间结构;它不能证明对象仍然存在、当前调用者有权访问它,或 Discord 正在返回公开资料。
常见错误
先把 ID 转成普通数字
这可能改变末尾数字。应保存原始字符串,并在位运算时使用 BigInt。
把所有数字 ID 都当成用户
用户、服务器、频道、身份组和消息共用 Snowflake。日期解码成功并不能识别对象类型。
把创建日期当成身份凭证
时间戳属于 Discord 对象,不必然代表当前展示该 ID 的人。它只能作为上下文,不能替代身份验证。
认为缺少资料就代表 ID 无效
公开资料可能因对象类型、接口返回、限流或账号状态而缺失。需要把本地解码结果与远程资料结果分开判断。
忽略时区比较格式化日期
跨地区比较时应使用 ISO 时间或毫秒值。本地化日期会受到时区和夏令时影响。
以上位结构和公式参考 Discord 的官方 Snowflake 文档。

