encryptionhahaha
Version:
`encryptionhahaha` 是一个趣味文本加密/解密工具,通过填充词和随机候选词组增加了加密的随机性,加解密过程完全可逆。
107 lines (98 loc) • 3.32 kB
JavaScript
// 通用加密模块,支持传递候选词组映射
// 定义填充词(1 字),确保它们不会出现在候选词组中
const fillerWords = ["呵", "啰", "呀"];
// 定义候选词组映射
const defaultCandidateMapping = {
"0": ["阿", "弥"],
"1": ["陀", "佛"],
"2": ["净", "土"],
"3": ["法", "界"],
"4": ["般", "若"],
"5": ["妙", "缘"],
"6": ["智", "慧"],
"7": ["无", "量"],
"8": ["寿", "延"],
"9": ["金", "刚"],
"a": ["如", "来"],
"b": ["虚", "空"],
"c": ["性", "悟"],
"d": ["莲", "华"],
"e": ["菩", "提"],
"f": ["涅", "槃"]
}
const defaultPrefix = "佛曰:";
// 随机生成填充词(组合成字符串),并且只有3%的概率会生成
function randomFiller() {
if (Math.random() > 0.03) return "";
// 直接返回一个随机填充词,不再生成多个
return fillerWords[Math.floor(Math.random() * fillerWords.length)];
}
// 加密函数:将原文转换为风格密文
function encrypt(text, prefix = defaultPrefix, candidateMapping = defaultCandidateMapping) {
let result = prefix;
for (const char of text) {
// 转换为 4 位十六进制,不足前补 0
const hex = char.charCodeAt(0).toString(16).padStart(4, '0');
for (const digit of hex) {
// 随机选取该数字的候选词组(1 字)
const candidates = candidateMapping[digit];
const token = candidates[Math.floor(Math.random() * candidates.length)];
result += token;
// 每32个编码块后才随机插入填充词,进一步减少填充词的频率
if ((result.length - prefix.length) % 32 === 0) {
result += randomFiller();
}
}
}
// 移除尾部填充词
return result;
}
// 解密函数:从密文中提取候选词组还原原文
function decrypt(encryptedText, prefix = defaultPrefix, candidateMapping = defaultCandidateMapping) {
// 构造反向映射:候选词组 -> 对应的十六进制数字
const reverseMapping = {};
for (const hex in candidateMapping) {
candidateMapping[hex].forEach(token => {
reverseMapping[token] = hex;
});
}
// 候选集合(所有候选词组),用于解密时判断
const candidateSet = new Set();
for (const arr of Object.values(candidateMapping)) {
arr.forEach(token => candidateSet.add(token));
}
// 检查并去除全局前缀
if (encryptedText.startsWith(prefix)) {
encryptedText = encryptedText.slice(prefix.length);
}
let hexStr = "";
let i = 0;
while (i < encryptedText.length) {
// 检查当前字符是否在候选集合中
const substr = encryptedText.substr(i, 1);
if (candidateSet.has(substr)) {
// 找到候选词组,提取对应十六进制数字
const hexDigit = reverseMapping[substr];
hexStr += hexDigit;
i += 1;
} else {
// 否则,视为填充词,跳过 1 个字符
i++;
}
}
// 校验提取的十六进制数字长度是否为 4 的倍数
if (hexStr.length % 4 !== 0) {
console.error("解密失败:提取的编码长度不正确");
return null;
}
let decrypted = "";
for (let i = 0; i < hexStr.length; i += 4) {
const hexCode = hexStr.slice(i, i + 4);
decrypted += String.fromCharCode(parseInt(hexCode, 16));
}
return decrypted;
}
export {
encrypt,
decrypt
};