Node.js 中用 SHA-256 检测重复正文:先定义规范化规则

举报
yd_240403232 发表于 2026/10/21 12:14:02 2026/10/21
【摘要】 从 Markdown 的换行与 BOM 规范化开始,用可运行的 SHA-256 示例检测重复正文,并说明持久化、状态核对和规则版本的边界。

同一篇 Markdown 文章可能来自网页输入框、Windows 编辑器和自动生成服务。直接比较字符串时,文件开头的 BOM 或不同的换行符就可能让两份内容看起来不同。反过来,如果为了去重把所有空白都删除,又可能误伤代码块中的缩进和字符串。

本文给出一个不依赖第三方包的最小示例:先明确允许忽略的文本差异,再计算 SHA-256,使用指纹检测相同正文。这里讨论的是内容去重,不是密码存储,也不保证识别语义相同的改写文章。

一、从可解释的规范化开始

示例只处理三类差异:文件开头的 BOM、CRLF 与 LF 换行,以及正文末尾的多余换行。不删除每一行的前导空格,不压缩代码块内部的空白,也不把全文变成小写。这样做的目标,是让规则足够明确,便于作者和维护者理解。

把以下内容保存为 content-hash.mjs,使用 Node.js 22 或以上版本执行:

import { createHash } from 'node:crypto';
import assert from 'node:assert/strict';

function normalizeMarkdown(text) {
  return text
    .replace(/^\uFEFF/, '')
    .replace(/\r\n?/g, '\n')
    .replace(/\n*$/, '\n');
}

function fingerprint(text) {
  return createHash('sha256')
    .update(normalizeMarkdown(text), 'utf8')
    .digest('hex');
}

const seen = new Set();
function accept(text) {
  const hash = fingerprint(text);
  if (seen.has(hash)) return false;
  seen.add(hash);
  return true;
}

const first = '# 示例\r\n\r\n正文内容\r\n';
const equivalent = '\uFEFF# 示例\n\n正文内容\n\n';
assert.equal(fingerprint(first), fingerprint(equivalent));
assert.equal(accept(first), true);
assert.equal(accept(equivalent), false);

// 缩进可能影响代码语义,因此保留这种差异。
assert.notEqual(fingerprint('    run()'), fingerprint('run()'));
console.log('首次接收成功;等价正文被识别为重复;缩进得到保留。');

运行 node content-hash.mjs,断言通过后会输出一行说明。把测试样例放在示例旁边,有助于在以后修改规范化规则时发现行为变化。

二、标题不应该掩盖重复正文

如果指纹的输入是“标题加正文”,只改标题就会得到新的指纹。需要判断正文是否重复时,应直接对正文建立指纹。标题、标签、作者和发布时间可以作为独立字段保存,供界面展示、检索和权限判断使用。

同样,不宜为了提高命中率把 Markdown 中所有空白合并。Python 缩进、代码字符串、表格和段落边界都可能受到影响。规范化不是越激进越好,应当由业务明确哪些差异可以忽略。

三、内存集合只能用于演示

示例中的 Set 在进程退出后会清空,因此不能单独作为长期运行任务的去重记录。实际应用需要将指纹、内容编号、所属账户和提交状态持久化。若多个进程会同时写入,应使用数据库唯一约束或其他能原子判断并写入的机制,不能仅靠“先查询,再插入”。

还应区分“内容重复”和“操作已经成功”。文章进入本地队列、保存云端草稿、提交发布、审核通过是不同阶段。保存过指纹并不能证明发布已经成功;网络超时也不能证明发布失败。写操作结果不明时,应查询官方状态后再决定是否继续,避免在自动重试中产生重复内容。

四、规则变更需要保留版本

如果将来增加 Unicode 规范化或调整末尾换行规则,旧指纹和新指纹可能不再可比。可以为指纹记录增加 normalizationVersion 字段,在迁移时根据原始正文重新计算,并先用样例验证差异。

SHA-256 的作用是把输入映射为固定长度的指纹。它不能判断两篇文章是否只是同义改写,也不能代替内容质量检查。去重规则、操作状态和人工核对各自解决不同的问题,组合起来才能让内容队列的行为清楚、可追踪。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。