UNPKG

encryptionhahaha

Version:

`encryptionhahaha` 是一个趣味文本加密/解密工具,通过填充词和随机候选词组增加了加密的随机性,加解密过程完全可逆。

107 lines (98 loc) 3.32 kB
// 通用加密模块,支持传递候选词组映射 // 定义填充词(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 };