generated from dellevin/template
编码解码网站
This commit is contained in:
@@ -15,8 +15,8 @@ except Exception as e:
|
||||
|
||||
model = "qwen3:1.7b"
|
||||
# model = "qwen3:0.6b"
|
||||
OLLAMA_BASE_URL = "http://127.0.0.1:11434/api/generate"
|
||||
# OLLAMA_BASE_URL = "http://152.136.153.72:27009/api/generate"
|
||||
# OLLAMA_BASE_URL = "http://127.0.0.1:11434/api/generate"
|
||||
OLLAMA_BASE_URL = "http://152.136.153.72:27009/api/generate"
|
||||
extracted_tags = ex_doc_tag.extract_tags_with_ollama_from_content(
|
||||
OLLAMA_BASE_URL,
|
||||
model,
|
||||
64
2.base64-de-in-code/api.py
Normal file
64
2.base64-de-in-code/api.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from flask import Flask, render_template, request, jsonify
|
||||
import base64
|
||||
import proj_utils.utils as utils # 导入你的工具模块
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/en-de-code')
|
||||
def index():
|
||||
"""渲染主页模板"""
|
||||
return render_template('en-de-code-index.html')
|
||||
|
||||
@app.route('/decode', methods=['POST'])
|
||||
def decode_endpoint():
|
||||
"""处理解码请求的 API 端点"""
|
||||
data = request.get_json()
|
||||
base64_input = data.get('input_text', '').strip()
|
||||
|
||||
if not base64_input:
|
||||
return jsonify({'success': False, 'error': '输入不能为空。'})
|
||||
|
||||
try:
|
||||
# 1. Base64 解码
|
||||
decoded_bytes = base64.b64decode(base64_input)
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'error': f'Base64 解码失败: {str(e)}'})
|
||||
|
||||
# 2. 使用 utils 模块中的 detect_and_decode 函数进行编码检测和解码
|
||||
decoded_result = utils.detect_and_decode(decoded_bytes)
|
||||
# 返回成功的 JSON 响应
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'result': decoded_result,
|
||||
})
|
||||
|
||||
@app.route('/encode', methods=['POST'])
|
||||
def encode_endpoint():
|
||||
"""处理编码请求的 API 端点"""
|
||||
data = request.get_json()
|
||||
text_to_encode = data.get('text_to_encode', '')
|
||||
encoding = data.get('encoding', 'utf-8') # 默认使用 UTF-8
|
||||
|
||||
if text_to_encode is None:
|
||||
return jsonify({'success': False, 'error': '输入不能为空。'})
|
||||
|
||||
try:
|
||||
# 1. 根据指定编码格式将文本转换为字节数组
|
||||
encoded_bytes = text_to_encode.encode(encoding)
|
||||
except LookupError:
|
||||
return jsonify({'success': False, 'error': f'未知的编码格式: {encoding}'})
|
||||
except UnicodeEncodeError as e:
|
||||
return jsonify({'success': False, 'error': f'编码失败: {str(e)}'})
|
||||
|
||||
# 2. 将字节数组进行 Base64 编码
|
||||
encoded_string = base64.b64encode(encoded_bytes).decode('ascii')
|
||||
|
||||
# 返回成功的 JSON 响应
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'result': encoded_string
|
||||
})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
34
2.base64-de-in-code/proj_utils/utils.py
Normal file
34
2.base64-de-in-code/proj_utils/utils.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import chardet
|
||||
|
||||
# 自动选择解码格式
|
||||
def detect_and_decode(data_bytes):
|
||||
"""使用 chardet 检测编码并解码"""
|
||||
# 使用 chardet 检测编码
|
||||
detected_encoding_info = chardet.detect(data_bytes)
|
||||
detected_encoding = detected_encoding_info.get('encoding')
|
||||
confidence = detected_encoding_info.get('confidence', 0)
|
||||
|
||||
if detected_encoding:
|
||||
try:
|
||||
decoded_string = data_bytes.decode(detected_encoding)
|
||||
print(f" - 使用检测到的编码 '{detected_encoding}' 成功解码,置信度:{confidence}")
|
||||
return decoded_string
|
||||
except UnicodeDecodeError as e:
|
||||
print(f" - 使用检测到的编码 '{detected_encoding}' 解码失败: {e}")
|
||||
|
||||
# 方法二:如果检测失败或置信度低,尝试常见的编码
|
||||
encodings_to_try = ['utf-8', 'gbk', 'gb2312', 'cp936']
|
||||
print(f" - 检测失败/置信度低,尝试常见编码")
|
||||
print(f" - 尝试常见编码列表: {encodings_to_try}")
|
||||
|
||||
for enc in encodings_to_try:
|
||||
try:
|
||||
decoded_string = data_bytes.decode(enc)
|
||||
print(f" - 成功使用编码 '{enc}' 解码。")
|
||||
return decoded_string
|
||||
except UnicodeDecodeError as e:
|
||||
print(f" - 尝试编码 '{enc}' 失败: {e}")
|
||||
continue
|
||||
# 如果所有方法都失败
|
||||
print(" - 所有编码尝试均失败。")
|
||||
return "所有编码尝试均失败。"
|
||||
120
2.base64-de-in-code/static/style.css
Normal file
120
2.base64-de-in-code/static/style.css
Normal file
@@ -0,0 +1,120 @@
|
||||
/* static/style.css */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background-color: #f6f8fa;
|
||||
color: #24292f;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column; /* 改为列布局 */
|
||||
align-items: center; /* 水平居中 */
|
||||
}
|
||||
|
||||
.page-header {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
width: 100%; /* 确保标题占据全宽 */
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
margin: 0 0 8px 0; /* 减少底部边距 */
|
||||
color: #24292f;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
margin: 4px 0;
|
||||
color: #57606a;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
width: 90%;
|
||||
max-width: 1600px; /* 增加最大宽度 */
|
||||
gap: 20px; /* 面板间距 */
|
||||
flex: 1; /* 容器占据剩余空间 */
|
||||
height: 60vh; /* 调整容器高度,给标题留出空间 */
|
||||
}
|
||||
|
||||
.panel {
|
||||
flex: 1; /* 左右各占50% */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #ffffff;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||
overflow: hidden; /* 防止内容溢出圆角 */
|
||||
}
|
||||
|
||||
.panel h2 {
|
||||
margin: 0;
|
||||
padding: 12px 16px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
background-color: #f6f8fa;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
color: #57606a;
|
||||
}
|
||||
|
||||
textarea {
|
||||
flex: 1; /* 占据剩余空间 */
|
||||
padding: 16px;
|
||||
border: none;
|
||||
resize: none; /* 禁用拖拽调整大小,由JS控制 */
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
background-color: #ffffff;
|
||||
color: #24292f;
|
||||
outline: none;
|
||||
font-family: inherit;
|
||||
min-height: 200px; /* 设置最小高度 */
|
||||
}
|
||||
|
||||
textarea:focus {
|
||||
/* Typecho 风格无明显焦点样式,保持简洁 */
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
justify-content: flex-end; /* 按钮靠右 */
|
||||
gap: 8px; /* 按钮间距 */
|
||||
padding: 12px 16px;
|
||||
background-color: #f6f8fa;
|
||||
border-top: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #24292f;
|
||||
background-color: #f6f8fa;
|
||||
border: 1px solid #d0d7de;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #f3f4f6;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #eaecef;
|
||||
}
|
||||
|
||||
button[type="submit"] {
|
||||
background-color: #238636; /* 绿色按钮 */
|
||||
color: white;
|
||||
border-color: #238636;
|
||||
}
|
||||
|
||||
button[type="submit"]:hover {
|
||||
background-color: #2ea043;
|
||||
}
|
||||
|
||||
button[type="submit"]:active {
|
||||
background-color: #3fb950;
|
||||
}
|
||||
149
2.base64-de-in-code/templates/en-de-code-index.html
Normal file
149
2.base64-de-in-code/templates/en-de-code-index.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Base64/编码检测与解码器 (Flask)</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 页面标题和说明 -->
|
||||
<div class="page-header">
|
||||
<h2>Base64 编码/解码器</h2>
|
||||
<p>因为其他网站base64解码都一坨屎,解码格式一直有问题,无法进行正常解码,要不然就是解码之后中文乱码了,所以写了这个demo</p>
|
||||
<p>接口地址:http(s)://网站域名/decode | http(s)://网站域名/encode</p>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<!-- 左侧面板 (输入) -->
|
||||
<div class="panel">
|
||||
<h2>输入(待编码/解码文本)</h2>
|
||||
<textarea
|
||||
id="inputText"
|
||||
placeholder="在此粘贴待处理的文本..."
|
||||
oninput="autoResize(this)"
|
||||
></textarea>
|
||||
<div class="controls">
|
||||
<button type="button" onclick="clearTextarea('inputText')">清空</button>
|
||||
<button type="button" onclick="process('encode')">编码</button>
|
||||
<button type="button" onclick="process('decode')">解码</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧面板 (输出) -->
|
||||
<div class="panel">
|
||||
<h2>输出</h2>
|
||||
<textarea
|
||||
id="outputResult"
|
||||
readonly
|
||||
placeholder="处理结果将显示在这里..."
|
||||
oninput="autoResize(this)"
|
||||
></textarea>
|
||||
<div class="controls">
|
||||
<button type="button" onclick="clearTextarea('outputResult')">清空</button>
|
||||
<button type="button" onclick="copyResult()">复制</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 自动调整 textarea 高度
|
||||
function autoResize(textarea) {
|
||||
textarea.style.height = 'auto';
|
||||
textarea.style.height = Math.min(textarea.scrollHeight, 400) + 'px'; // 最大高度400px
|
||||
}
|
||||
|
||||
// 清空指定的 textarea
|
||||
function clearTextarea(id) {
|
||||
const element = document.getElementById(id);
|
||||
element.value = '';
|
||||
autoResize(element); // 清空后重置高度
|
||||
}
|
||||
|
||||
// 主处理函数 (根据传入的 mode 决定是编码还是解码)
|
||||
async function process(mode) {
|
||||
const inputElement = document.getElementById('inputText');
|
||||
const outputResult = document.getElementById('outputResult');
|
||||
const inputValue = inputElement.value.trim();
|
||||
|
||||
if (!inputValue) {
|
||||
alert('输入不能为空!');
|
||||
return;
|
||||
}
|
||||
|
||||
let endpoint = '';
|
||||
let payload = {};
|
||||
|
||||
if (mode === 'decode') {
|
||||
endpoint = '/decode';
|
||||
payload.input_text = inputValue;
|
||||
} else if (mode === 'encode') {
|
||||
endpoint = '/encode';
|
||||
payload.text_to_encode = inputValue;
|
||||
// 使用默认编码 UTF-8
|
||||
payload.encoding = 'utf-8';
|
||||
} else {
|
||||
alert('未知的处理模式');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
outputResult.value = data.result;
|
||||
autoResize(outputResult); // 处理后调整高度
|
||||
} else {
|
||||
outputResult.value = `错误: ${data.error}`;
|
||||
autoResize(outputResult);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`请求失败:`, error);
|
||||
outputResult.value = `请求失败: ${error.message}`;
|
||||
autoResize(outputResult);
|
||||
}
|
||||
}
|
||||
|
||||
// 复制结果到剪贴板
|
||||
function copyResult() {
|
||||
const outputResult = document.getElementById('outputResult');
|
||||
if (outputResult.value === '') {
|
||||
alert('没有内容可复制!');
|
||||
return;
|
||||
}
|
||||
|
||||
outputResult.select();
|
||||
outputResult.setSelectionRange(0, 99999); // 为了移动端兼容
|
||||
|
||||
try {
|
||||
const successful = document.execCommand('copy');
|
||||
if (successful) {
|
||||
// 临时提示
|
||||
const originalText = document.querySelector('.panel:nth-child(2) .controls button:last-child').innerText;
|
||||
document.querySelector('.panel:nth-child(2) .controls button:last-child').innerText = '已复制!';
|
||||
setTimeout(() => {
|
||||
document.querySelector('.panel:nth-child(2) .controls button:last-child').innerText = originalText;
|
||||
}, 2000);
|
||||
} else {
|
||||
alert('复制失败,请手动选择复制。');
|
||||
}
|
||||
} catch (err) {
|
||||
alert('浏览器不支持自动复制,请手动选择复制。');
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载后聚焦到输入框
|
||||
window.onload = function() {
|
||||
document.getElementById('inputText').focus();
|
||||
};
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user