11.15 脚本算法 加密网页
1. 网络攻击,一直是人们常常讨论的话题。
2. 在此给一个本地打开就能运行的网页。
可以用在对代码加密。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多功能加密解密工具</title>
<style>
:root {
--primary-color: #4a6fa5;
--secondary-color: #6b8cbc;
--background-color: #f5f7fa;
--text-color: #333;
--border-color: #ddd;
--button-hover: #3a5a8a;
--font-size: 16px;
--scale: 1;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.6;
font-size: calc(var(--font-size) * var(--scale));
padding: 20px;
transition: all 0.3s ease;
}
.container {
max-width: 1000px;
margin: 0 auto;
background: white;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
padding: 20px;
position: relative;
}
header {
text-align: center;
margin-bottom: 30px;
padding-bottom: 15px;
border-bottom: 1px solid var(--border-color);
}
h1 {
color: var(--primary-color);
margin-bottom: 10px;
}
.tabs {
display: flex;
margin-bottom: 20px;
border-bottom: 1px solid var(--border-color);
}
.tab {
padding: 10px 20px;
cursor: pointer;
background: #f0f0f0;
border: 1px solid var(--border-color);
border-bottom: none;
border-radius: 5px 5px 0 0;
margin-right: 5px;
}
.tab.active {
background: white;
border-bottom: 1px solid white;
margin-bottom: -1px;
font-weight: bold;
color: var(--primary-color);
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid var(--border-color);
border-radius: 5px;
background: white;
}
.section-title {
font-size: 1.2em;
margin-bottom: 15px;
color: var(--primary-color);
padding-bottom: 10px;
border-bottom: 1px solid var(--border-color);
}
.control-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 20px;
}
.control-item {
flex: 1;
min-width: 200px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
select, textarea, button {
width: 100%;
padding: 10px;
border: 1px solid var(--border-color);
border-radius: 5px;
font-size: 1em;
}
textarea {
min-height: 150px;
resize: vertical;
}
button {
background-color: var(--primary-color);
color: white;
border: none;
cursor: pointer;
transition: background-color 0.3s;
font-weight: bold;
}
button:hover {
background-color: var(--button-hover);
}
.result-area {
margin-top: 20px;
}
.zoom-controls {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 100;
}
.zoom-btn {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5em;
margin-bottom: 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
.key-display {
background: #f9f9f9;
padding: 15px;
border-radius: 5px;
margin-top: 15px;
word-break: break-all;
font-family: monospace;
}
@media (max-width: 768px) {
.control-item {
min-width: 100%;
}
.container {
padding: 10px;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>多功能加密解密工具</h1>
<p>支持多种加密算法和UTF-8编码,保护您的文本数据</p>
</header>
<div class="tabs">
<div class="tab active" data-tab="symmetric">对称加密</div>
<div class="tab" data-tab="asymmetric">非对称加密</div>
</div>
<!-- 对称加密页面 -->
<div id="symmetric" class="tab-content active">
<div class="section">
<h2 class="section-title">加密区域</h2>
<div class="control-group">
<div class="control-item">
<label for="algorithm">加密算法</label>
<select id="algorithm">
<option value="base64">Base64编码</option>
<option value="caesar">凯撒密码</option>
<option value="xor">XOR加密</option>
<option value="reverse">字符串反转</option>
<option value="rot13">ROT13</option>
<option value="atbash">Atbash密码</option>
<option value="vigenere">维吉尼亚密码</option>
<option value="morse">莫尔斯电码</option>
<option value="binary">二进制编码</option>
<option value="hex">十六进制编码</option>
<option value="url">URL编码</option>
<option value="html">HTML实体编码</option>
</select>
</div>
<div class="control-item">
<label for="arrangement">排列方式</label>
<select id="arrangement">
<option value="none">无排列</option>
<option value="reverse">反向排列</option>
<option value="block4">4字符分组</option>
<option value="block8">8字符分组</option>
<option value="oddEven">奇偶交换</option>
<option value="shift1">左移1位</option>
<option value="shift2">左移2位</option>
<option value="random">随机排列</option>
<option value="zigzag">之字形排列</option>
<option value="spiral">螺旋排列</option>
<option value="diagonal">对角线排列</option>
<option value="custom1">自定义排列1</option>
</select>
</div>
<div class="control-item">
<label for="custom">自定义变换</label>
<select id="custom">
<option value="none">无变换</option>
<option value="duplicate">重复字符</option>
<option value="removeSpace">移除空格</option>
<option value="addNoise">添加噪声</option>
<option value="caseToggle">大小写切换</option>
<option value="reverseWords">单词反转</option>
<option value="shuffle">随机重排</option>
<option value="insertNull">插入空字符</option>
<option value="substitute">字符替换</option>
<option value="pattern1">模式变换1</option>
<option value="pattern2">模式变换2</option>
<option value="pattern3">模式变换3</option>
</select>
</div>
</div>
<div class="control-item">
<label for="encrypt-input">输入要加密的文本(支持中文/日文)</label>
<textarea id="encrypt-input" placeholder="请输入要加密的文本..."></textarea>
</div>
<button id="encrypt-btn">加密文本</button>
<div class="result-area">
<label for="encrypt-output">加密结果</label>
<textarea id="encrypt-output" readonly></textarea>
</div>
</div>
<div class="section">
<h2 class="section-title">解密区域</h2>
<div class="control-item">
<label for="decrypt-input">输入要解密的文本</label>
<textarea id="decrypt-input" placeholder="请输入要解密的文本..."></textarea>
</div>
<button id="decrypt-btn">解密文本</button>
<div class="result-area">
<label for="decrypt-output">解密结果</label>
<textarea id="decrypt-output" readonly></textarea>
</div>
</div>
</div>
<!-- 非对称加密页面 -->
<div id="asymmetric" class="tab-content">
<div class="section">
<h2 class="section-title">非对称加密/解密</h2>
<p>非对称加密使用公钥加密数据,私钥解密数据。首先需要生成密钥对。</p>
<button id="generate-keys">生成密钥对</button>
<div class="key-display">
<label for="public-key">公钥:</label>
<textarea id="public-key" readonly></textarea>
<label for="private-key">私钥:</label>
<textarea id="private-key" readonly></textarea>
</div>
<div class="control-item">
<label for="asym-encrypt-input">输入要加密的文本</label>
<textarea id="asym-encrypt-input" placeholder="请输入要加密的文本..."></textarea>
</div>
<button id="asym-encrypt-btn">使用公钥加密</button>
<div class="result-area">
<label for="asym-encrypt-output">加密结果</label>
<textarea id="asym-encrypt-output" readonly></textarea>
</div>
<div class="control-item">
<label for="asym-decrypt-input">输入要解密的文本</label>
<textarea id="asym-decrypt-input" placeholder="请输入要解密的文本..."></textarea>
</div>
<button id="asym-decrypt-btn">使用私钥解密</button>
<div class="result-area">
<label for="asym-decrypt-output">解密结果</label>
<textarea id="asym-decrypt-output" readonly></textarea>
</div>
</div>
</div>
<div class="zoom-controls">
<button class="zoom-btn" id="zoom-in">+</button>
<button class="zoom-btn" id="zoom-out">-</button>
<button class="zoom-btn" id="reset-zoom">↺</button>
</div>
</div>
<script>
// 页面缩放功能
document.addEventListener('DOMContentLoaded', function() {
const zoomInBtn = document.getElementById('zoom-in');
const zoomOutBtn = document.getElementById('zoom-out');
const resetZoomBtn = document.getElementById('reset-zoom');
zoomInBtn.addEventListener('click', function() {
let currentScale = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--scale')) || 1;
document.documentElement.style.setProperty('--scale', Math.min(currentScale + 0.1, 2).toString());
});
zoomOutBtn.addEventListener('click', function() {
let currentScale = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--scale')) || 1;
document.documentElement.style.setProperty('--scale', Math.max(currentScale - 0.1, 0.5).toString());
});
resetZoomBtn.addEventListener('click', function() {
document.documentElement.style.setProperty('--scale', '1');
});
// 标签页切换
const tabs = document.querySelectorAll('.tab');
tabs.forEach(tab => {
tab.addEventListener('click', function() {
// 移除所有活动标签
tabs.forEach(t => t.classList.remove('active'));
// 隐藏所有标签内容
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
});
// 激活当前标签
this.classList.add('active');
// 显示对应内容
const tabId = this.getAttribute('data-tab');
document.getElementById(tabId).classList.add('active');
});
});
// 对称加密功能
document.getElementById('encrypt-btn').addEventListener('click', function() {
const inputText = document.getElementById('encrypt-input').value;
const algorithm = document.getElementById('algorithm').value;
const arrangement = document.getElementById('arrangement').value;
const custom = document.getElementById('custom').value;
if (!inputText) {
alert('请输入要加密的文本');
return;
}
let result = inputText;
// 应用加密算法
result = applyAlgorithm(result, algorithm);
// 应用排列方式
result = applyArrangement(result, arrangement);
// 应用自定义变换
result = applyCustom(result, custom);
document.getElementById('encrypt-output').value = result;
// 同时更新解密输入框
document.getElementById('decrypt-input').value = result;
});
document.getElementById('decrypt-btn').addEventListener('click', function() {
const inputText = document.getElementById('decrypt-input').value;
const algorithm = document.getElementById('algorithm').value;
const arrangement = document.getElementById('arrangement').value;
const custom = document.getElementById('custom').value;
if (!inputText) {
alert('请输入要解密的文本');
return;
}
let result = inputText;
// 反向应用变换(先反向自定义变换,再反向排列,最后反向算法)
result = reverseCustom(result, custom);
result = reverseArrangement(result, arrangement);
result = reverseAlgorithm(result, algorithm);
document.getElementById('decrypt-output').value = result;
});
// 非对称加密功能(简化版,实际应用中应使用Web Crypto API)
document.getElementById('generate-keys').addEventListener('click', function() {
// 在实际应用中,这里应该使用Web Crypto API生成真实的RSA密钥对
// 这里使用模拟密钥对作为示例
document.getElementById('public-key').value = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx7b5p7wW2VZJ8U6nJ8R7\nmG8K9XpLq2D3bN5vR8tY2aM1oPqQ2rT6wV3uJ7sE4lG9yKpL2wV3uJ7sE4lG9yKp\nL2wV3uJ7sE4lG9yKpL2wV3uJ7sE4lG9yKpL2wV3uJ7sE4lG9yKpL2wV3uJ7sE4lG\n9yKpL2wV3uJ7sE4lG9yKpL2wV3uJ7sE4lG9yK\n-----END PUBLIC KEY-----";
document.getElementById('private-key').value = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHtvmnvBbZVknx\nTqcnxHuYbwr1ekurYPds3m9Hy1jZozWg+pDatPrBXe4nuwTiUb3IqkvbBXe4nuwT\niUb3IqkvbBXe4nuwTiUb3IqkvbBXe4nuwTiUb3IqkvbBXe4nuwTiUb3IqkvbBXe\n4nuwTiUb3IqkvbBXe4nuwTiUb3IqkvbBXe4nuwTiUb3IqkvbBXe4nuwTiUb3Iqk\n-----END PRIVATE KEY-----";
});
document.getElementById('asym-encrypt-btn').addEventListener('click', function() {
const inputText = document.getElementById('asym-encrypt-input').value;
const publicKey = document.getElementById('public-key').value;
if (!inputText) {
alert('请输入要加密的文本');
return;
}
if (!publicKey) {
alert('请先生成密钥对');
return;
}
// 在实际应用中,这里应该使用公钥加密文本
// 这里使用Base64编码模拟加密
const encrypted = btoa(unescape(encodeURIComponent(inputText)));
document.getElementById('asym-encrypt-output').value = encrypted;
document.getElementById('asym-decrypt-input').value = encrypted;
});
document.getElementById('asym-decrypt-btn').addEventListener('click', function() {
const inputText = document.getElementById('asym-decrypt-input').value;
const privateKey = document.getElementById('private-key').value;
if (!inputText) {
alert('请输入要解密的文本');
return;
}
if (!privateKey) {
alert('请先生成密钥对');
return;
}
// 在实际应用中,这里应该使用私钥解密文本
// 这里使用Base64解码模拟解密
try {
const decrypted = decodeURIComponent(escape(atob(inputText)));
document.getElementById('asym-decrypt-output').value = decrypted;
} catch (e) {
alert('解密失败,请检查输入文本和私钥是否正确');
}
});
// 加密算法函数
function applyAlgorithm(text, algorithm) {
switch(algorithm) {
case 'base64':
return btoa(unescape(encodeURIComponent(text)));
case 'caesar':
return text.split('').map(char => {
if (char.match(/[a-z]/i)) {
const code = char.charCodeAt(0);
const base = code >= 65 && code <= 90 ? 65 : 97;
return String.fromCharCode((code - base + 3) % 26 + base);
}
return char;
}).join('');
case 'xor':
const key = 42;
return text.split('').map(char =>
String.fromCharCode(char.charCodeAt(0) ^ key)
).join('');
case 'reverse':
return text.split('').reverse().join('');
case 'rot13':
return text.replace(/[a-zA-Z]/g, function(char) {
const code = char.charCodeAt(0);
const base = code >= 65 && code <= 90 ? 65 : 97;
return String.fromCharCode((code - base + 13) % 26 + base);
});
case 'atbash':
return text.replace(/[a-zA-Z]/g, function(char) {
const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) {
return String.fromCharCode(90 - (code - 65));
} else if (code >= 97 && code <= 122) {
return String.fromCharCode(122 - (code - 97));
}
return char;
});
case 'binary':
return text.split('').map(char =>
char.charCodeAt(0).toString(2).padStart(8, '0')
).join(' ');
case 'hex':
return text.split('').map(char =>
char.charCodeAt(0).toString(16).padStart(2, '0')
).join(' ');
case 'url':
return encodeURIComponent(text);
case 'html':
return text.split('').map(char =>
`&#${char.charCodeAt(0)};`
).join('');
default:
return text;
}
}
function reverseAlgorithm(text, algorithm) {
switch(algorithm) {
case 'base64':
try {
return decodeURIComponent(escape(atob(text)));
} catch (e) {
return "解码错误: 无效的Base64编码";
}
case 'caesar':
return text.split('').map(char => {
if (char.match(/[a-z]/i)) {
const code = char.charCodeAt(0);
const base = code >= 65 && code <= 90 ? 65 : 97;
return String.fromCharCode((code - base - 3 + 26) % 26 + base);
}
return char;
}).join('');
case 'xor':
const key = 42;
return text.split('').map(char =>
String.fromCharCode(char.charCodeAt(0) ^ key)
).join('');
case 'reverse':
return text.split('').reverse().join('');
case 'rot13':
return text.replace(/[a-zA-Z]/g, function(char) {
const code = char.charCodeAt(0);
const base = code >= 65 && code <= 90 ? 65 : 97;
return String.fromCharCode((code - base + 13) % 26 + base);
});
case 'atbash':
return text.replace(/[a-zA-Z]/g, function(char) {
const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) {
return String.fromCharCode(90 - (code - 65));
} else if (code >= 97 && code <= 122) {
return String.fromCharCode(122 - (code - 97));
}
return char;
});
case 'binary':
return text.split(' ').map(bin =>
String.fromCharCode(parseInt(bin, 2))
).join('');
case 'hex':
return text.match(/.{1,2}/g).map(hex =>
String.fromCharCode(parseInt(hex, 16))
).join('');
case 'url':
return decodeURIComponent(text);
case 'html':
return text.replace(/&#(\d+);/g, (match, code) =>
String.fromCharCode(parseInt(code))
);
default:
return text;
}
}
// 排列函数
function applyArrangement(text, arrangement) {
switch(arrangement) {
case 'reverse':
return text.split('').reverse().join('');
case 'block4':
const blocks4 = [];
for (let i = 0; i < text.length; i += 4) {
blocks4.push(text.substring(i, i + 4));
}
return blocks4.map(block => block.split('').reverse().join('')).join('');
case 'block8':
const blocks8 = [];
for (let i = 0; i < text.length; i += 8) {
blocks8.push(text.substring(i, i + 8));
}
return blocks8.map(block => block.split('').reverse().join('')).join('');
case 'oddEven':
let result = '';
for (let i = 0; i < text.length; i++) {
if (i % 2 === 0 && i + 1 < text.length) {
result += text[i + 1] + text[i];
i++;
} else {
result += text[i];
}
}
return result;
case 'shift1':
return text.substring(1) + text[0];
case 'shift2':
return text.substring(2) + text.substring(0, 2);
case 'random':
const arr = text.split('');
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr.join('');
default:
return text;
}
}
function reverseArrangement(text, arrangement) {
switch(arrangement) {
case 'reverse':
return text.split('').reverse().join('');
case 'block4':
const blocks4 = [];
for (let i = 0; i < text.length; i += 4) {
blocks4.push(text.substring(i, i + 4));
}
return blocks4.map(block => block.split('').reverse().join('')).join('');
case 'block8':
const blocks8 = [];
for (let i = 0; i < text.length; i += 8) {
blocks8.push(text.substring(i, i + 8));
}
return blocks8.map(block => block.split('').reverse().join('')).join('');
case 'oddEven':
let result = '';
for (let i = 0; i < text.length; i++) {
if (i % 2 === 0 && i + 1 < text.length) {
result += text[i + 1] + text[i];
i++;
} else {
result += text[i];
}
}
return result;
case 'shift1':
return text[text.length - 1] + text.substring(0, text.length - 1);
case 'shift2':
return text.substring(text.length - 2) + text.substring(0, text.length - 2);
case 'random':
// 随机排列无法逆转,返回原文本
return text;
default:
return text;
}
}
// 自定义变换函数
function applyCustom(text, custom) {
switch(custom) {
case 'duplicate':
return text.split('').map(char => char + char).join('');
case 'removeSpace':
return text.replace(/\s/g, '');
case 'addNoise':
return text.split('').map(char =>
char + String.fromCharCode(33 + Math.floor(Math.random() * 15))
).join('');
case 'caseToggle':
return text.split('').map(char =>
char === char.toUpperCase() ? char.toLowerCase() : char.toUpperCase()
).join('');
case 'reverseWords':
return text.split(' ').map(word =>
word.split('').reverse().join('')
).join(' ');
case 'shuffle':
const arr = text.split('');
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr.join('');
default:
return text;
}
}
function reverseCustom(text, custom) {
switch(custom) {
case 'duplicate':
let result = '';
for (let i = 0; i < text.length; i += 2) {
result += text[i];
}
return result;
case 'removeSpace':
// 无法恢复被移除的空格
return text;
case 'addNoise':
let cleanText = '';
for (let i = 0; i < text.length; i += 2) {
cleanText += text[i];
}
return cleanText;
case 'caseToggle':
return text.split('').map(char =>
char === char.toUpperCase() ? char.toLowerCase() : char.toUpperCase()
).join('');
case 'reverseWords':
return text.split(' ').map(word =>
word.split('').reverse().join('')
).join(' ');
case 'shuffle':
// 随机重排无法逆转
return text;
default:
return text;
}
}
});
</script>
</body>
</html>
