347 lines
10 KiB
Python
347 lines
10 KiB
Python
import base64
|
||
from konabot.plugins.handle_text.base import (
|
||
TextHandleResult,
|
||
TextHandler,
|
||
TextHandlerEnvironment,
|
||
)
|
||
|
||
|
||
class THBase64(TextHandler):
|
||
name = "b64"
|
||
keywords = ["base64"]
|
||
|
||
async def handle(
|
||
self, env: TextHandlerEnvironment, istream: str | None, args: list[str]
|
||
) -> TextHandleResult:
|
||
# 用法: b64 encode/decode [encoding] [text]
|
||
if not args and istream is None:
|
||
return TextHandleResult(
|
||
1, "用法:b64 <encode|decode> [编码, 默认utf-8] [文本]"
|
||
)
|
||
|
||
mode = args[0].lower() if args else "encode"
|
||
encoding = args[1] if len(args) > 1 else "utf-8"
|
||
|
||
# 确定输入源
|
||
text = (
|
||
istream
|
||
if istream is not None
|
||
else (" ".join(args[2:]) if len(args) > 2 else "")
|
||
)
|
||
if not text:
|
||
return TextHandleResult(1, "输入文本为空")
|
||
|
||
try:
|
||
if mode == "encode":
|
||
res = base64.b64encode(text.encode(encoding, "replace")).decode("ascii")
|
||
else:
|
||
res = base64.b64decode(text.encode("ascii")).decode(encoding, "replace")
|
||
return TextHandleResult(0, res)
|
||
except Exception as e:
|
||
return TextHandleResult(1, f"Base64 转换失败: {str(e)}")
|
||
|
||
|
||
class THCaesar(TextHandler):
|
||
name = "caesar"
|
||
keywords = ["凯撒", "rot"]
|
||
|
||
async def handle(
|
||
self, env: TextHandlerEnvironment, istream: str | None, args: list[str]
|
||
) -> TextHandleResult:
|
||
# 用法: caesar <shift> [text]
|
||
shift = int(args[0]) if args else 13
|
||
text = (
|
||
istream
|
||
if istream is not None
|
||
else (" ".join(args[1:]) if len(args) > 1 else "")
|
||
)
|
||
|
||
def _shift(char):
|
||
if not char.isalpha():
|
||
return char
|
||
start = ord("A") if char.isupper() else ord("a")
|
||
return chr((ord(char) - start + shift) % 26 + start)
|
||
|
||
res = "".join(_shift(c) for c in text)
|
||
return TextHandleResult(0, res)
|
||
|
||
|
||
class THReverse(TextHandler):
|
||
name = "reverse"
|
||
keywords = ["rev", "反转"]
|
||
|
||
async def handle(
|
||
self, env: TextHandlerEnvironment, istream: str | None, args: list[str]
|
||
) -> TextHandleResult:
|
||
text = istream if istream is not None else (" ".join(args) if args else "")
|
||
return TextHandleResult(0, text[::-1])
|
||
|
||
|
||
class THMorse(TextHandler):
|
||
name = "morse"
|
||
keywords = ["摩斯", "decode_morse"]
|
||
|
||
# 国际摩斯电码表 (部分)
|
||
MORSE_EN = {
|
||
".-": "A",
|
||
"-...": "B",
|
||
"-.-.": "C",
|
||
"-..": "D",
|
||
".": "E",
|
||
"..-.": "F",
|
||
"--.": "G",
|
||
"....": "H",
|
||
"..": "I",
|
||
".---": "J",
|
||
"-.-": "K",
|
||
".-..": "L",
|
||
"--": "M",
|
||
"-.": "N",
|
||
"---": "O",
|
||
".--.": "P",
|
||
"--.-": "Q",
|
||
".-.": "R",
|
||
"...": "S",
|
||
"-": "T",
|
||
"..-": "U",
|
||
"...-": "V",
|
||
".--": "W",
|
||
"-..-": "X",
|
||
"-.--": "Y",
|
||
"--..": "Z",
|
||
"-----": "0",
|
||
".----": "1",
|
||
"..---": "2",
|
||
"...--": "3",
|
||
"....-": "4",
|
||
".....": "5",
|
||
"-....": "6",
|
||
"--...": "7",
|
||
"---..": "8",
|
||
"----.": "9",
|
||
"/": " ",
|
||
}
|
||
|
||
# 日文和文摩斯电码表 (Wabun Code)
|
||
MORSE_JP = {
|
||
"--.--": "ア",
|
||
".-": "イ",
|
||
"..-": "ウ",
|
||
"-.---": "エ",
|
||
".-...": "オ",
|
||
".-..": "カ",
|
||
"-.-..": "キ",
|
||
"...-": "ク",
|
||
"-.--": "ケ",
|
||
"----": "コ",
|
||
"-.-.-": "サ",
|
||
"--.-.": "シ",
|
||
"---.-": "ス",
|
||
".---.": "セ",
|
||
"---.": "ソ",
|
||
"-.": "タ",
|
||
"..-.": "チ",
|
||
".--.": "ツ",
|
||
".-.--": "テ",
|
||
"..-..": "ト",
|
||
".-.": "ナ",
|
||
"-.-.": "ニ",
|
||
"....": "ヌ",
|
||
"--.-": "ネ",
|
||
"..--": "ノ",
|
||
"-...": "ハ",
|
||
"--..-": "ヒ",
|
||
"--..": "フ",
|
||
".": "ヘ",
|
||
"-..": "ホ",
|
||
"-..-": "マ",
|
||
"..-.-": "ミ",
|
||
"-": "ム",
|
||
"-...-": "メ",
|
||
"-..-.": "モ",
|
||
".--": "ヤ",
|
||
"-..--": "ユ",
|
||
"--": "ヨ",
|
||
"...": "ラ",
|
||
"--.": "リ",
|
||
"-.--.": "ル",
|
||
"---": "レ",
|
||
".-.-": "ロ",
|
||
"-.-": "ワ",
|
||
".-..-": "ヰ",
|
||
".--..": "ヱ",
|
||
".---": "ヲ",
|
||
".-.-.": "ン",
|
||
"-..-.--.": "ッ",
|
||
"-..-.--": "ャ",
|
||
"-..--..--": "ュ",
|
||
"-..---": "ョ",
|
||
"-..---.--": "ァ",
|
||
"-..-.-": "ィ",
|
||
"-..-..-": "ゥ",
|
||
"-..--.---": "ェ",
|
||
"-..-.-...": "ォ",
|
||
"-..-.-..": "ヵ",
|
||
"-..--.--": "ヶ",
|
||
"..": "゛",
|
||
"..--.": "゜",
|
||
".--.-": "ー",
|
||
".-.-.-": "、",
|
||
".-.-..": "。",
|
||
"-.--.-": "(",
|
||
".-..-.": ")",
|
||
}
|
||
|
||
async def handle(
|
||
self, env: TextHandlerEnvironment, istream: str | None, args: list[str]
|
||
) -> TextHandleResult:
|
||
"""
|
||
用法: morse <mode: en|jp> [text]
|
||
例子: morse en .... . .-.. .-.. ---
|
||
"""
|
||
if not args and istream is None:
|
||
return TextHandleResult(
|
||
1, "用法:morse <en|jp> <电码>。使用空格分隔字符,/ 分隔单词。"
|
||
)
|
||
|
||
mode = args[0].lower() if args else "en"
|
||
text = (
|
||
istream
|
||
if istream is not None
|
||
else (" ".join(args[1:]) if len(args) > 1 else "")
|
||
)
|
||
|
||
if not text:
|
||
return TextHandleResult(1, "请输入电码内容")
|
||
|
||
# 选择词典
|
||
mapping = self.MORSE_JP if mode == "jp" else self.MORSE_EN
|
||
|
||
try:
|
||
# 按空格切分符号,过滤掉多余空位
|
||
tokens = [t for t in text.split(" ") if t]
|
||
decoded = []
|
||
|
||
for token in tokens:
|
||
# 处理部分解谜中可能出现的换行或特殊斜杠
|
||
token = token.strip()
|
||
if token in mapping:
|
||
decoded.append(mapping[token])
|
||
else:
|
||
decoded.append("[?]") # 无法识别的符号
|
||
|
||
return TextHandleResult(0, "".join(decoded))
|
||
except Exception as e:
|
||
return TextHandleResult(1, f"摩斯电码解析出错: {str(e)}")
|
||
|
||
|
||
class THBaseConv(TextHandler):
|
||
name = "baseconv"
|
||
keywords = ["进制转换"]
|
||
|
||
async def handle(self, env: TextHandlerEnvironment, istream: str | None, args: list[str]) -> TextHandleResult:
|
||
# 用法: baseconv <src_base> <dst_base> [text]
|
||
if len(args) < 2 and istream is None:
|
||
return TextHandleResult(1, "用法:baseconv <原进制> <目标进制> [文本]")
|
||
|
||
src_base = int(args[0])
|
||
dst_base = int(args[1])
|
||
val_str = istream if istream is not None else "".join(args[2:])
|
||
|
||
try:
|
||
# 先转为 10 进制中间量,再转为目标进制
|
||
decimal_val = int(val_str, src_base)
|
||
|
||
if dst_base == 10:
|
||
res = str(decimal_val)
|
||
elif dst_base == 16:
|
||
res = hex(decimal_val)[2:]
|
||
else:
|
||
# 通用任意进制转换逻辑
|
||
chars = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||
res = ""
|
||
temp = decimal_val
|
||
while temp > 0:
|
||
res = chars[temp % dst_base] + res
|
||
temp //= dst_base
|
||
res = res or "0"
|
||
|
||
return TextHandleResult(0, res.upper() if dst_base == 16 else res)
|
||
except Exception as e:
|
||
return TextHandleResult(1, f"转换失败: {str(e)}")
|
||
|
||
|
||
class THAlphaConv(TextHandler):
|
||
name = "alphaconv"
|
||
keywords = ["字母表转换"]
|
||
|
||
async def handle(self, env: TextHandlerEnvironment, istream: str | None, args: list[str]) -> TextHandleResult:
|
||
# 用法: alphaconv <alphabet> <to_hex|from_hex> [text]
|
||
if len(args) < 2:
|
||
return TextHandleResult(1, "用法:alphaconv <字母表> <to_hex|from_hex> [文本]")
|
||
|
||
alphabet = args[0]
|
||
mode = args[1].lower()
|
||
base = len(alphabet)
|
||
text = istream if istream is not None else "".join(args[2:])
|
||
|
||
try:
|
||
if mode == "to_hex":
|
||
# 自定义字母表 -> 10进制 -> 16进制
|
||
val = 0
|
||
for char in text:
|
||
val = val * base + alphabet.index(char)
|
||
return TextHandleResult(0, hex(val)[2:])
|
||
else:
|
||
# 16进制 -> 10进制 -> 自定义字母表
|
||
val = int(text, 16)
|
||
res = ""
|
||
while val > 0:
|
||
res = alphabet[val % base] + res
|
||
val //= base
|
||
return TextHandleResult(0, res or alphabet[0])
|
||
except Exception as e:
|
||
return TextHandleResult(1, f"字母表转换失败: {str(e)}")
|
||
|
||
|
||
class THB64Hex(TextHandler):
|
||
name = "b64hex"
|
||
|
||
async def handle(self, env: TextHandlerEnvironment, istream: str | None, args: list[str]) -> TextHandleResult:
|
||
# 用法: b64hex <enc|dec> [text]
|
||
mode = args[0] if args else "dec"
|
||
text = istream if istream is not None else "".join(args[1:])
|
||
|
||
try:
|
||
if mode == "enc": # Hex -> B64
|
||
raw_bytes = bytes.fromhex(text)
|
||
res = base64.b64encode(raw_bytes).decode()
|
||
else: # B64 -> Hex
|
||
raw_bytes = base64.b64decode(text)
|
||
res = raw_bytes.hex()
|
||
return TextHandleResult(0, res)
|
||
except Exception as e:
|
||
return TextHandleResult(1, f"Base64-Hex 转换失败: {str(e)}")
|
||
|
||
|
||
class THAlign(TextHandler):
|
||
name = "align"
|
||
keywords = ["format", "排版"]
|
||
|
||
async def handle(self, env: TextHandlerEnvironment, istream: str | None, args: list[str]) -> TextHandleResult:
|
||
# 用法: align <n:每组长度> <m:每行组数> [text]
|
||
# 例子: align 2 8 (即 2个一组,8组一行,类似 0011 2233...)
|
||
n = int(args[0]) if len(args) > 0 else 2
|
||
m = int(args[1]) if len(args) > 1 else 8
|
||
text = istream if istream is not None else "".join(args[2:])
|
||
|
||
# 移除现有空格换行以便重新排版
|
||
text = "".join(text.split())
|
||
|
||
chunks = [text[i:i+n] for i in range(0, len(text), n)]
|
||
lines = []
|
||
for i in range(0, len(chunks), m):
|
||
lines.append(" ".join(chunks[i:i+m]))
|
||
|
||
return TextHandleResult(0, "\n".join(lines))
|