设计一个简单的[JS]文本摘要算法

网站cookie中有一段用户信息(包括微信用户信息,用户关联信息)的文本,使用entrance键存储,选择不同的条件后文本内容也不同,cookie上的值也会变化。本来的打算是通过将entrance值存储在sessionstorage,然后通过比较当前请求中cookie的值与sessionstorage的值是否一致来得出用户是否选择了其他条件从而进行其他操作。

但是不想将entrance键的值直接存储到sessionstorage中,一来该值内容较长,基本上超过1000个字符,二来只是为了进行比较操作就存储原始的用户信息做法不是很友好。

所以想要一个简单的文本摘要算法,以达到上述诉求。在网络上搜索了一番,并没有一个零依赖,简单的文本摘要算法。只好自己理了下思路写出了一个简单的文本摘要算法。分享出来,以飨读者。

/**
 * 简单的文本摘要算法。
 * ! 不要用于敏感业务
 * @param {String} text 待摘要的文本,必需
 * @param {String} salt 加盐内容
 * @param {Number} caesar 凯撒字符偏移长度
 * @param {Object} opts 其他配置项
 * @property {Number} opts.blockLength 分块长度
 */
export default function textSummary(
  text = "",
  salt = "[简单]文本摘要算法",
  caesar = 5,
  opts = {}
) {
  if (typeof text !== "string") {
    throw new Error("entrance value must be a string");
  }

  const { blockLength = 16 } = opts;

  if (blockLength >= 36 || blockLength < 16) {
    throw new Error(
      "blockLength options prop is wrong value, it is value in range:16~36"
    );
  }

  // 加盐
  const textArr = `${text};salt=${salt}`.split("");

  const _0bTextArr = textArr
    .map(str => str.codePointAt(0) + caesar) // 凯撒字符偏移
    .map(num => num.toString(2)); // 转化为二进制

  // 分块
  const _0bTextStr = _0bTextArr.join("");
  const blockAmount = Math.ceil(_0bTextStr.length / blockLength);
  const _0bTextBlockArr = Array(blockAmount);

  for (let i = 0; i < blockAmount; i++) {
    let subStr = _0bTextStr.slice(i * blockLength, (i + 1) * blockLength);

    // 最后一块字符长度不足,补0
    if (subStr.length !== blockLength) {
      subStr = subStr.padEnd(blockLength, "0");
    }

    _0bTextBlockArr[i] = subStr;
  }

  // 将二进制块转化为16进制块
  const _0xTextBlockArr = _0bTextBlockArr.map(str =>
    parseInt(str, 2).toString(blockLength)
  );
  const result = _0xTextBlockArr.join("");

  return result;
}

算法设计思路是:

  1. 对原始文本进行加盐处理。
  2. 获取到处理后文本的Unicode字符码点位置,并将获取到的位置进行凯撒字符偏移处理。
  3. 将偏移后的位置(为十进制的结果)转化为二进制。
  4. 对整个二进制文本按指定的块长度进行分块处理。最后一块内容如果字符长度不足,则补0。
  5. 将分好的每个块的二进制内容转为十六进制内容。
  6. 将得到的每个块的十六进制内容拼接在一起并返回其值。

思考了下,由于在步骤4对最后一块内容进行了补0操作,导致该块内容在逆处理时得不到肯定的值,从而导致算法不可逆。

本算法虽说是摘要算法,但实质上有加密,线性压缩的一点功能。但还好已经满足了原本的要求。

posted @ 2019-10-29 23:28  西河  阅读(23)  评论(0编辑  收藏  举报