大家好!
这是我的 tnfy.link 系列的第二部分 - 深入研究另一个 URL 缩短器! 这篇文章重点讨论短链接生成的复杂性。 虽然看似简单,但选择最佳方法却面临着独特的挑战。
本质上,生成短链接涉及为每个长 URL 创建一个简洁、唯一的标识符。此 ID 必须满足几个条件:
经过彻底调查,我确定了四种创建短链接的主要方法。让我们详细研究一下它们。
最直接的方法是利用随机字节生成和后续编码。然而,区分伪随机和加密安全随机数生成至关重要。
Go 的 math/rand
包提供了伪随机数生成器(PRNG)。 使用相同的种子(初始值)始终会产生相同的数字序列。 虽然足以满足许多应用程序的需要,但它不适合安全或不可预测的链接生成。
为了增强安全性,crypto/rand
包是更好的选择。它利用系统噪声来生成真正随机且不可预测的值 - 想想电磁噪声。 这保证了高熵,但依赖主机获取随机数据的虚拟机在重负载下可能会遇到生成速度较慢的情况。
原始随机字节不适合 URL;编码是必要的。常见的编码技术包括:
对于用户友好的短链接,Base58 提供了紧凑性和抗错误性的最佳平衡。
要点:
哈希根据输入生成固定长度的值(例如长 URL)。 虽然保证一致性(相同的输入总是产生相同的输出),但它缺乏随机性。 因此,重复缩短相同的 URL 会产生相同的 ID,从而无法满足不可预测性要求。
在散列之前添加随机盐会引入可变性,但使用原始随机字节变得更简单、更高效。
通用唯一标识符(UUID)广泛用于唯一值生成。 它们的默认格式对于短链接来说太长,但重新编码(例如,在 Base58 中)可以减小大小。
NanoID 是一种替代方案,它使用可自定义的字母表生成较短的字符串(默认为 21 个字符),从而优化了可读性和抗错性。
为什么要避免 UUID?
UUID 从根本上依赖于随机字节,与直接生成随机值相比没有显着优势。
随机值生成有时会导致重复,特别是在高负载或 ID 较短的情况下。 虽然 tnfy.link 并非专为高负载场景而设计,但潜在问题值得考虑。
顺序计数器本质上保证了唯一性。 Redis使用INCR命令可以实现分布式计数器的实现。 然而,顺序 ID 是可以预测的。将序列与随机字节相结合可以解决这个问题,确保唯一性和不可预测性。
例如:
注意:顺序组件可能会显示生成的链接总数,这在某些情况下可能是不受欢迎的。
这篇文章探讨了各种短链接生成方法:
对于大多数应用程序,Base58 编码的随机字节 就足够了。 对于高负载冲突处理,将随机字节与顺序组件组合起来是稳健的。 虽然尚未在 tnfy.link 的后端实现,但计划作为未来的可选功能。
感谢您的阅读! 欢迎您在评论中提供有关链接生成的反馈!
相关帖子
有关我的项目的更多信息,请参阅我关于 Android 短信网关的文章。
以上是tnfy.link - ID 怎么样?的详细内容。更多信息请关注PHP中文网其他相关文章!