文章和评论都是一篇 Markdown 文档,并且是完全独立的。当:
- 渲染同一篇文章的内容和评论的内容
- 同时渲染多篇文章的内容(比如碎碎念)
时,由于脚注的编号生成规则是完全一样的,所以就会生成编号相同的脚注。 那么,文章之间的“查看引用”以及评论的“查看引用”就会完全乱了套。
文章、评论、脚注都有各自的编号空间,所以如果需要严格全局不冲突,需要加上类型限定。比如:“article-123-footnote-456
” 或者 “comment-123-footnote-456
”。
以上是真正意义上的全局唯一不冲突的编号方案。但是我觉得好长,而且跟路径前面的文章编号和评论编号重复出现,有点丑。
我决定给它们哈希成一段固定长度的字符串1。使用的算法和之前给用户邮箱头像做哈希的算法一样:FNV-1a。
被哈希的数据即是上面加上类型限定的完整编号,哈希结果是 uint32
。然后将其输出为 16 进制,加上 fn:
前缀。最终形如:fn:12345678
。
使用哈希是会有冲突的,而内容的渲染顺序也是不定的,所以即便是全局使用一个哈希表,我也没办法控制每次哈希同样的数据时生成同样的结果,所以现在的哈希表干脆是定义在“一篇内容”中的。当然,不管放在哪里,都要解决冲突,我使用了最简单的开放寻址法。后续如果发现在全局范围内冲突较多,我再解决。我感觉可能性很低,即便相对于 sha256 来说 fnv32 的值空间仅有非常少的 个。
几年前就注意到了这个问题,只是懒。