pmarreck/printable-binary

GitHub: pmarreck/printable-binary

PrintableBinary 是一款跨平台的二进制数据编码解码工具,旨在将二进制内容转换为人类可读的 UTF-8 文本,便于在终端和文本环境中安全查看和共享。

Stars: 1 | Forks: 0

# PrintableBinary [![Garnix CI](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgarnix.io%2Fapi%2Fbadges%2Fpmarreck%2Fprintable-binary%3Fbranch%3Dyolo)](https://garnix.io/repo/pmarreck/printable-binary) [![GitHub CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/ad31b292d7115722.svg)](https://github.com/pmarreck/printable-binary/actions/workflows/ci.yml) 一款跨平台的实用工具(包含 LuaJIT、C、Zig 和 JavaScript 实现),用于将任意二进制数据编码为人类可读的 UTF-8 文本,然后再将其解码回原始二进制数据。 ## 概述 PrintableBinary 旨在将二进制数据序列化/反序列化为一种视觉上独特、人类可读的格式,该格式也支持复制粘贴,并可嵌入任何支持 UTF-8 的环境中。它是十六进制编码的一种替代方案,提供了更好的视觉密度,并能立即识别出嵌入的 ASCII 文本,同时也能将二进制数据融入基于文本的格式(如 JSON、TOML、XML、YAML 等),而不会出现转义问题。 此实现允许您在终端中直接查看二进制数据(它甚至带有 `--passthrough` 管道检查模式),而不会破坏显示,这使得它在调试、日志记录、以人类可读的形式共享二进制数据,甚至将文件拖放到 Web 界面进行即时编码/解码方面特别有用。 ## 功能特性 - **多实现**:以 LuaJIT 脚本、编译后的 C 二进制文件、Zig 二进制文件和 JavaScript 模块(由浏览器 UI 和 Node.js 工具共享)的形式提供,具有最大灵活性 - **Web 与 Node.js 工具**:拖放式浏览器界面和基于 Node 的 CLI 包装器共享相同的编码/解码核心,支持跨平台工作流 - **视觉独特的字符**:256 个可能的字节值中的每一个都映射到一个唯一的、视觉上独特的 UTF-8 字符 - **ASCII 透传**:标准可打印 ASCII 字符(32-126)基本上保持原样,便于即时识别 - **Shell 安全编码**:可能引发 shell 问题的特殊字符使用安全的 Unicode 替代方案进行编码 - **单字符宽度**:每个编码表示形式在等宽终端中都渲染为单个字符宽度 - **紧凑性**:使用 1-3 字节的 UTF-8 字符以实现最佳空间效率 - **易用性**:编码后的字符串易于复制、粘贴和打印 - **格式化**:可自定义输出格式,支持分组大小和行宽选项 - **二进制安全**:在编码和解码时保留所有二进制数据,包括 NUL 字节 - **透传模式**:同时将原始二进制数据输出到 stdout,并将编码文本输出到 stderr,适用于灵活的处理管道 ### 实际益处(为什么使用这个?) - **人类可扫描的快照**:比十六进制更密集,比 Base64 更易读;非常适合需要字面量 UTF-8 而不是转义十六进制块的固件/测试。 - **更好的差异比较和可搜索性**:控制字符和空格是显式的,因此结构一目了然;比 `strings(1)` 功能丰富得多,后者会丢弃大部分字节。 - **可调试的日志和粘贴板**:可打印、可逆,经过 Slack/电子邮件/维基处理后不会被破坏或换行损坏。 - **小型二进制固件**:将头部、协议帧、证书等嵌入文本文件,同时保持补丁/友好搜索的便利性。 - **跨平台**:可在任何能运行 LuaJIT/Node 或构建 C 版本的地方工作。 - **等宽安全字形集**:每个字形都经过验证,在常见等宽字体中占据相同的宽度,因此在编辑器/终端/差异比较中的对齐保持完整(令人惊讶的是,许多 Unicode 符号做不到这一点)。 ### 与十六进制编码对比 - **更高的屏幕显示密度**:十六进制每个字节需要两个字形;PrintableBinary 将每个字节映射到单个可见字符,因此您每行可以看到大约两倍的数据量,同时仍保持 UTF-8 安全性。 - **ASCII 突出显示**:可打印 ASCII 字节保持不变(除了那些对 shell 不友好的符号,它们使用相似的替代品),因此嵌入的文本是立即可读的,而不需要在心里解码十六进制对。 - **控制字符被标记**:字节 0–31 和 DEL 渲染为助记符号(`⏎`、`↧`、`⌫` 等),使结构和控制流一目了然,无需额外工具。 - **权衡**:十六进制在字节上扩展数据正好 2 倍。PrintableBinary 在现实世界的二进制文件上平均约为 1.8–1.9 倍(得益于许多 1 字节和 2 字节 UTF-8 映射),最坏情况下仅接近 3 倍。这点额外的代价换来了显著提高的可读性和粘贴安全性。 ## 性能 Zig 实现通过源代码级别的数据结构改进和可选的 PGO(性能引导优化)对吞吐量进行了深度优化: | 实现 | 编码 (10 MB) | 解码 (10 MB) | 编码吞吐量 | 解码吞吐量 | |---|---|---|---|---| | **Zig** | 51 ms | 62 ms | 121 MB/s | 108 MB/s | | **PGO (C FFI + Zig)** | 50 ms | 63 ms | 125 MB/s | 109 MB/s | | **C (独立)** | — | — | 与 Zig 相当 | 与 Zig 相当 | | **Lua (LuaJIT)** | 233 ms | 2,510 ms | 86 MB/s | 3.9 MB/s | Zig 核心的主要优化: - **预分配缓冲区**:预先确定编码/解码输出的大小(热循环中无增长检查) - **扁平字符映射表**:编译期构建的连续字节缓冲区(约 1.5 KB),取代 256 个分散的指针——可放入 L1 缓存 - **O(1) 解码查找**:针对 1 字节、2 字节和 3 字节 UTF-8 序列的直接查找表,取代 O(log 256) 的二进制搜索 - **无内部解码循环**:每个字符只需一次 UTF-8 长度检查和直接查找 这些源代码级更改相比初始的 ReleaseFast 构建,**编码速度提升了 16%**,**解码速度提升了 61% (2.6倍)**。PGO 路径 (`make pgo-ffi`) 通过配置文件引导的分支布局额外提供约 1-3% 的提升,使用 C FFI 命令行工具通过其公共 C ABI 来实际测试 Zig 库。 基准测试在 Apple M4 上运行,使用 `hyperfine --warmup 5 --min-runs 20` 对 `/dev/urandom` 生成的随机二进制数据进行测试。 ## 使用方法 ### 作为命令行工具 ``` # Use any implementation: # LuaJIT version: ./bin/printable-binary # Node.js CLI: ./bin/printable-binary-node.js # C version: make release && ./bin/printable-binary-c # Zig version: nix build .#printableBinaryZig && ./bin/printable-binary-zig # (Examples below use the LuaJIT version; the others accept the same flags.) # Encode binary data echo -n "Hello, World!" | ./bin/printable-binary # Output: Hello,␣World﹗ # Note: Direct encoding of binary data as command-line arguments is not supported # because shell environments cannot represent all binary data (such as NUL bytes) # Always pipe input or specify a file to encode # Encode a file ./bin/printable-binary somefile.bin > encoded.txt # Encode with formatting (groups of 8 characters, 10 groups per line) ./bin/printable-binary -f somefile.bin > formatted_encoded.txt # Encode with custom formatting (groups of 4 characters, 16 groups per line) ./bin/printable-binary -f=4x16 somefile.bin > custom_formatted.txt # Inspect the active character map (table/JSON/CSV) ./bin/printable-binary --mappings | head ./bin/printable-binary-c --mappings-json > mapping.json ./bin/printable-binary-node.js --mappings-csv > mapping.csv # Decode data (whitespace is ignored during decoding) echo -n "Hello,␣World﹗" | ./bin/printable-binary -d # Output: Hello, World! # Decode formatted data (formatting is ignored) cat formatted_encoded.txt | ./bin/printable-binary -d > original.bin # Preserve literal whitespace (spaces, tabs, newlines stay as-is instead of being encoded) echo -n "A B C" | ./bin/printable-binary --spaces > encoded_with_spaces.txt ./bin/printable-binary -d -S encoded_with_spaces.txt > restored.bin # Preserve all whitespace (shorthand for -s -t -n) ./bin/printable-binary -w input.bin > with_whitespace.txt # Preserve specific characters (e.g., keep ! and " literal) ./bin/printable-binary -p '!"' input.bin > preserved.txt # Decode block-formatted input (strip whitespace separators first) ./bin/printable-binary -d -S formatted_encoded.txt > original.bin # Use passthrough mode to output both original binary (stdout) and encoded text (stderr) # This is useful for binary data processing pipelines that need both representations echo -n "Hello, World!" | ./bin/printable-binary --passthrough 2>encoded.txt | wc -c # Binary data goes to stdout, encoded text to stderr # Use the C implementation for better performance on large files ./bin/printable-binary-c large_file.bin > encoded_large.txt ``` ### 网页界面 - 在线演示: - 拖放或浏览以编码任何文件;`.pbt` 上传会自动解码回其原始二进制形式。 - 大型输出(>1 MB)会跳过文本框以避免浏览器卡顿——使用下载按钮获取 UTF-8 文本。 - 默认换行是每行 75 个字符,以平衡可读性和密度;复制/下载按钮重用 CLI 和 Node 实现产生的确切字节。 - 要在本地修改,可在任何现代浏览器中打开 `docs/index.html`(或 `index.html`);该页面加载共享的 `js/printable_binary.js` 模块,无需构建步骤。 ### 作为 Lua 库 ``` local PrintableBinary = require("printable_binary") -- Encode binary data local binary_data = "Hello, World!" local encoded = PrintableBinary.encode(binary_data) print(encoded) -- Output: Hello,␣World! -- Decode back to binary local decoded = PrintableBinary.decode(encoded) print(decoded) -- Output: Hello, World! ``` ### 作为 JavaScript 模块 ``` import PrintableBinary from './js/printable_binary.js'; const pb = new PrintableBinary(); const input = new Uint8Array([0x00, 0xFF, 0x41]); // Encode to printable UTF-8 const encoded = pb.encode(input, { format: '75x1' }); console.log(encoded); // Decode back to bytes const decoded = pb.decode(encoded); console.log(Array.from(decoded)); // [0, 255, 65] // Preserve literal spaces (tabs/newlines/CR still ignored on decode) const encodedSpaces = pb.encodeString('A B C', { spaces: true }); const decodedSpaces = pb.decodeToString(encodedSpaces, { spaces: true }); ``` 相同的模块驱动浏览器 UI,并可在 Node.js (ESM) 中运行或打包用于其他环境。 ### JavaScript CLI 为了与 LuaJIT/C 工具在命令行上保持一致,请使用基于 Node 的包装器: ``` # Encode (auto-detects stdin vs. file) ./bin/printable-binary-node.js input.bin > encoded.pbt # Decode (whitespace is ignored automatically) ./bin/printable-binary-node.js --decode encoded.pbt > restored.bin # Apply formatting (e.g., 75 characters per line) ./bin/printable-binary-node.js --format 75x1 input.bin > formatted.pbt # Pipe data through stdin cat input.bin | ./bin/printable-binary-node.js -f=8x10 > encoded.txt # Dump the current character map ./bin/printable-binary-node.js --mappings-json > map.json ``` 支持的标志:`-d/--decode`、`-f/--format NxM`、`-s/--spaces`、`--mappings*`、`-h/--help`。CLI 与浏览器 UI 共享完全相同的编码/解码实现。 ### 字符映射表 每个 CLI(以及构建后的 WASM 版本)都内嵌了规范的 256 项表,因此您随时可以检查它: ``` ./bin/printable-binary --mappings # human-readable table ./bin/printable-binary --mappings-json # machine-readable JSON ./bin/printable-binary --mappings-csv # spreadsheet-friendly CSV ``` 这些命令显示的是当前活动的映射表。要覆盖默认值,请将一个 `character_map.txt` 文件放在可执行文件旁边(或设置 `PRINTABLE_BINARY_MAP` 环境变量),然后重新运行相同的标志以确认您的更改。文件格式很简单:**256 行 UTF-8 文本,每行一个字形,对应从 0x00 开始的字节值**。没有逗号、空格或索引——只有按顺序排列的字面字符。编辑后,运行 `./utils/audit_character_map.lua character_map.txt`(以及在 Unicode 发布新宽度表时运行 `./utils/update_eaw_data.sh`),还有 `./utils/generate_embedded_map.lua` 以便嵌入的头部保持同步。 运行时查找顺序为: 1. `PRINTABLE_BINARY_MAP` 环境变量(文件路径) 2. 位于可执行文件/模块旁边的 `character_map.txt` 文件(`bin/printable-binary`、`js/printable_binary.js`、`bin/printable-binary-c` 或 WASM 目录) 3. 当前工作目录 如果这些位置都不存在,则自动使用内嵌的表。编辑文件以尝试替代字形——LuaJIT、C、Node.js 和 WebAssembly 实现都将在下次运行时遵守此覆盖。 ### 环境变量 PrintableBinary 在所有实现(LuaJIT、C、WASM、Node 和测试)中都遵循几个环境变量: - `PRINTABLE_BINARY_MAP` – 覆盖内嵌表的 `character_map.txt` 文件的绝对或相对路径。查找顺序如上所述。 - `PRINTABLE_BINARY_MUTE_STATS` – 设置为 `1`、`true` 或 `yes` 以抑制通常写入 stderr 的“已编码...”/“解码模式...”统计信息。这对于期望干净 stderr 输出同时仍重用默认交互行为的脚本非常有用。 使用 wazero 启动 WASM 构建时,请记住它**不会**继承主机环境变量,除非您显式传递它们。构建 `bin/printable-binary.wasm`(例如通过 `make wasm`)后,使用 `wazero run --env=PRINTABLE_BINARY_MUTE_STATS=true bin/printable-binary.wasm`(或使用 `--env-inherit` 转发所有变量),以便行为与原生二进制文件保持一致。 ### 检查流(透传模式) 一个强大的技巧是将 PrintableBinary 放入管道中,以便在原始字节继续向下游传递的同时,在 stderr 上查看编码流: ``` # Monitor traffic but keep the pipeline lossless tcpdump -i en0 -w - | \ ./bin/printable-binary --passthrough > capture.raw 2> capture.pbt # Alternatively inspect a decompression stream: gzip -c bigfile > /tmp/data.gz gzip -dc /tmp/data.gz | \ ./bin/printable-binary --passthrough | md5sum # stdout (original bytes) flows into md5sum; stderr shows the printable view. ``` 因为 `--passthrough` 将原始二进制数据发送到 stdout,所以您可以在 Unix 管道中的任何位置插入 PrintableBinary 以进行可观测性检查,而无需修改数据流。 ### 现实用法示例 - **免转义的 JSON 嵌入** – 通过预先编码字节,然后将其直接放入 JSON 字符串,避免反斜杠/引号地狱: ``` ENCODED="$(./bin/printable-binary secret.bin)" printf '{"payload":"%s"}\n' "$ENCODED" | jq . # 稍后解码: printf '%s' "$ENCODED" | ./bin/printable-binary -d > restored.bin ``` - **Bash 对二进制片段的断言** – 在 here-doc 中内联保持固件,无需转义。生成编码块一次(例如,`PRINTABLE_BINARY_MUTE_STATS=1 printf 'CAFÉ\n' | ./bin/printable-binary`),然后将其粘贴到 here-doc 中: ``` want=$'CAFÉ\n' # 逐字节期望值 got=$(./bin/printable-binary -d <<'EOF' CAFĹɃ¶ EOF ) [[ "$got" == "$want" ]] || { echo "mismatch"; exit 1; } ``` - **就地查看混合二进制/文本流** – 镜像一个活动的 HTTP POST,同时保持原始字节不变: ``` nc -l 8080 | ./bin/printable-binary --passthrough \ >requests.raw 2>requests.pbt # tail -f requests.pbt 查看头部+正文,不会出现乱码。 ``` - **网页嵌入 + JS 解码** – 将二进制数据作为纯文本嵌入 HTML,然后在浏览器中使用共享模块将其恢复: ```html ``` - **查看常见格式的魔数字节** – 无需十六进制查看器即可发现魔数: ``` head -c 16 some.pdf | ./bin/printable-binary # 预期看到 %PDF␣1.7… 直接渲染出来。 head -c 8 image.png | ./bin/printable-binary # 如果 PNG 签名完整,应显示 89PNG⏎␣␣。 ``` ## 格式兼容性 PrintableBinary 字符集专为与常见文本格式高度兼容而设计: ### ✅ **兼容性极佳的格式:** - **JSON** - 在引号字符串中完美表现(我们将 `"` 重新编码为 `ˮ`) - **XML/HTML** - 在文本内容和属性中完美表现(我们的编码中没有 `<>&`) - **TOML** - 在引号字符串中完美表现 - **YAML** - 在引号字符串中完美表现,在无引号上下文中表现良好 - **C/C++/Java 等** - 在字符串字面量中完美表现(我们将 `\` 重新编码为 `⧹`) - **Shell 脚本** - 在引号字符串中完美表现(我们将 `'` 重新编码为 `ʼ`) - **SQL** - 在引号字符串中完美表现 - **大多数支持 UTF-8 的文本格式** ### 🎯 **兼容性关键设计决策:** - **双引号** (34) → `ˮ` (U+02EE) - 避免 JSON/XML 属性冲突 - **单引号** (39) → `ʼ` (U+02BC) - 避免 shell/SQL 冲突 - **反斜杠** (92) → `⧹` (U+29F9) - 避免转义序列问题 - **控制字符** → 安全的 Unicode 符号(·, ¶, ⏎ 等) - 我们的特殊编码中**没有问题分隔符** ### 📝 **使用建议:** ``` # JSON echo '{"binary_data": "'$(./bin/printable-binary file.bin)'"}' # XML/HTML echo ''$(./bin/printable-binary file.bin)'' # YAML echo 'data: "'$(./bin/printable-binary file.bin)'"' # Shell variable DATA="$(./bin/printable-binary file.bin)" # C string literal printf 'char data[] = "%s";\n' "$(./bin/printable-binary file.bin)" ``` **注意:** 如果您的原始二进制数据包含有问题字符(如 `{`),它们将原样显示,因为它们是可打印的 ASCII。在嵌入结构化格式时请使用引号上下文。 ## 字形选择设计哲学 替换字形的选择旨在平衡三个相互竞争的目标: 1. **字节经济性** - 尽可能优先选择较短的 UTF-8 序列(1-2 字节)以最小化编码开销。大多数可打印 ASCII 以 1:1 通过,因此文本密集的数据扩展最小;纯随机二进制数据平均约为 1.85 倍。 2. **视觉暗示** - 每个字形应暗示它所替代的内容。例如: - `␣` (开放方框) 代表空格 - 清楚地表示“这里有一个空格” - `⏎` 代表回车 - 通用的“返回/回车”符号 - `⇥` 代表制表符 - 指向条形的箭头暗示制表 - `˂˃` 代表尖括号 - 形状相似,明显相关 3. **明确区分** - 字形**不得**与原始字符混淆。这解释了如下选择: - `ˮ` 代表双引号 - 修饰字母双撇号,视觉上形象且只有 2 字节 - `ʼ` 代表单引号 - 修饰字母撇号看起来相似但明显不同 - `⧷` 代表反斜杠 - 中间带有一条水平线 **高字节排序 (0x80-0xFF):** 扩展字节映射大致按词法顺序排列 - 它们以 A 的变体(ă, Ă, Ǎ...)开始,以 Z 的变体(ź, Ź, ž, Ž, ż, Ż)结束。这允许开发人员只需瞥一眼字形的基本字母,就能大致猜测所表示的字节值。 ## 字符编码 - **控制字符 (0-31)**:映射到视觉上独特的符号,如 ·, ¯, «, », µ 等。 - **空格 (32)**:编码为 ␣ 以提高可见性 - **Shell 不安全的 ASCII 字符**:映射到安全的 Unicode 替代方案: - 感叹号 (33) → ﹗ (U+FE57) 小型感叹号 - 双引号 (34) → ˮ (U+02EE) 修饰字母双撇号 - 井号 (35) → ♯ (U+266F) 音乐升号 - 美元符号 (36) → ﹩ (U+FE69) 小型美元符号 - 百分号 (37) → ﹪ (U+FE6A) 小型百分号 - & 号 (38) → ⅋ (U+214B) 翻转的 & 号 - 单引号 (39) → ʼ (U+02BC) 修饰字母撇号 - 圆括号 (40-41) → ❨❩ (U+2768-2769) 中型圆括号装饰符 - 星号 (42) → ﹡ (U+FE61) 小型星号 - 加号 (43) → ﹢ (U+FE62) 小型加号 - 减号 (45) → ﹣ (U+FE63) 小型连字符减号 - 斜杠 (47) → ⁄ (U+2044) 分数斜线 - 冒号 (58) → ꞉ (U+A789) 修饰字母冒号 - 分号 (59) → ; (U+037E) 希腊问号 - 等号 (61) → ꞊ (U+A78A) 修饰字母短等号 - 问号 (63) → Ɂ (U+0241) 拉丁大写字母声门塞音 - @ 符号 (64) → @ (U+0040) 商业符号 - 反斜杠 (92) → ⧷ (U+29F7) 带水平线的反斜线 - 方括号 (91, 93) → ⟦⟧ (U+27E6-27E7) 数学白色方括号 - 反引号 (96) → ˋ (U+02CB) 修饰字母重音符 - 花括号 (123-125) → ❴∣❵(装饰符和数学变体) - 波浪号 (126) → ˜ (U+02DC) 小型波浪号 - **DEL (127)**:编码为 ⌦ - **扩展字节 (128-255)**:直接取自 `character_map.txt` 并按字母顺序分组,以便相邻字节共享相关的字形 ### 完整字符映射参考 此表根据 `character_map.txt` 生成,以确保所有实现保持同步: | 字节 | 字符 | Unicode | UTF-8 | 名称 | | --- | --- | --- | --- | --- | | 0 | · | U+00B7 | C2 B7 | 中点 | | 1 | ¯ | U+00AF | C2 AF | 长音符号 | | 2 | « | U+00AB | C2 AB | 左双角引号 | | 3 | » | U+00BB | C2 BB | 右双角引号 | | 4 | ϟ | U+03DF | CF 9F | 希腊小写字母 Koppa | | 5 | ¿ | U+00BF | C2 BF | 倒置问号 | | 6 | ¡ | U+00A1 | C2 A1 | 倒置感叹号 | | 7 | ª | U+00AA | C2 AA | 阴性序数标识符 | | 8 | ⌫ | U+232B | E2 8C AB | 向左擦除 | | 9 | ⇥ | U+21E5 | E2 87 A5 | 右向条形箭头 | | 10 | ¶ | U+00B6 | C2 B6 | 段落符号 | | 11 | ↧ | U+21A7 | E2 86 A7 | 从条形向下的箭头 | | 12 | § | U+00A7 | C2 A7 | 分节符号 | | 13 | ⏎ | U+23CE | E2 8F 8E | 返回符号 | | 14 | ȯ | U+022F | C8 AF | 带上点的拉丁小写字母 O | | 15 | ʘ | U+0298 | CA 98 | 拉丁字母双唇搭嘴音 | | 16 | Ɣ | U+0194 | C6 94 | 拉丁大写字母 Gamma | | 17 | ¹ | U+00B9 | C2 B9 | 上标一 | | 18 | ² | U+00B2 | C2 B2 | 上标二 | | 19 | º | U+00BA | C2 BA | 阳性序数标识符 | | 20 | ³ | U+00B3 | C2 B3 | 上标三 | | 21 | µ | U+00B5 | C2 B5 | 微符号 | | 22 | ɨ | U+0268 | C9 A8 | 带笔划的拉丁小写字母 I | | 23 | ⏹ | U+23F9 | E2 8F B9 | 停止用黑方块 | | 24 | © | U+00A9 | C2 A9 | 版权符号 | | 25 | ¦ | U+00A6 | C2 A6 | 断竖线 | | 26 | Ƶ | U+01B5 | C6 B5 | 带笔划的拉丁大写字母 Z | | 27 | ⎋ | U+238B | E2 8E 8B | 带西北箭头的断裂圆圈 | | 28 | Ξ | U+039E | CE 9E | 希腊大写字母 Xi | | 29 | ǁ | U+01C1 | C7 81 | 拉丁字母边搭嘴音 | | 30 | ǀ | U+01C0 | C7 80 | 拉丁字母齿搭嘴音 | | 31 | ¬ | U+00AC | C2 AC | 否定符号 | | 32 | ␣ | U+2423 | E2 90 A3 | 开方框 | | 33 | ǃ | U+01C3 | C7 83 | 拉丁字母卷舌搭嘴音 | | 34 | ˮ | U+02EE | CB AE | 修饰字母双撇号 | | 35 | ♯ | U+266F | E2 99 AF | 音乐升号 | | 36 | Ꞩ | U+A7A8 | EA 9E A8 | 带斜笔划的拉丁大写字母 S | | 37 | ‰ | U+2030 | E2 80 B0 | 千分号 | | 38 | ⅋ | U+214B | E2 85 8B | 翻转的 & 号 | | 39 | ʼ | U+02BC | CA BC | 修饰字母撇号 | | 40 | ❨ | U+2768 | E2 9D A8 | 中型左圆括号装饰符 | | 41 | ❩ | U+2769 | E2 9D A9 | 中型右圆括号装饰符 | | 42 | ⁎ | U+204E | E2 81 8E | 低位星号 | | 43 | ⨦ | U+2A26 | E2 A8 A6 | 带下波浪线的加号 | | 44 | , | U+002C | 2C | 逗号 | | 45 | ˗ | U+02D7 | CB 97 | 修饰字母减号 | | 46 | . | U+002E | 2E | 句号 | | 47 | ⁄ | U+2044 | E2 81 84 | 分数斜线 | | 48 | 0 | U+0030 | 30 | 数字零 | | 49 | 1 | U+0031 | 31 | 数字一 | | 50 | 2 | U+0032 | 32 | 数字二 | | 51 | 3 | U+0033 | 33 | 数字三 | | 52 | 4 | U+0034 | 34 | 数字四 | | 53 | 5 | U+0035 | 35 | 数字五 | | 54 | 6 | U+0036 | 36 | 数字六 | | 55 | 7 | U+0037 | 37 | 数字七 | | 56 | 8 | U+0038 | 38 | 数字八 | | 57 | 9 | U+0039 | 39 | 数字九 | | 58 | ꞉ | U+A789 | EA 9E 89 | 修饰字母冒号 | | 59 | ; | U+037E | CD BE | 希腊问号 | | 60 | ˂ | U+02C2 | 3C | 修饰字母左箭头 | | 61 | ꞊ | U+A78A | EA 9E 8A | 修饰字母短等号 | | 62 | ˃ | U+02C3 | 3E | 修饰字母右箭头 | | 63 | Ɂ | U+0241 | C9 81 | 拉丁大写字母声门塞音 | | 64 | @ | U+0040 | 40 | 商业符号 | | 65 | A | U+0041 | 41 | 拉丁大写字母 A | | 66 | B | U+0042 | 42 | 拉丁大写字母 B | | 67 | C | U+0043 | 43 | 拉丁大写字母 C | | 68 | D | U+0044 | 44 | 拉丁大写字母 D | | 69 | E | U+0045 | 45 | 母 E | | 70 | F | U+0046 | 46 | 拉丁大写字母 F | | 71 | G | U+0047 | 47 | 拉丁大写字母 G | | 72 | H | U+0048 | 48 | 拉丁大写字母 H | | 73 | I | U+0049 | 49 | 拉丁大写字母 I | | 74 | J | U+004A | 4A | 拉丁大写字母 J | | 75 | K | U+004B | 4B | 拉丁大写字母 K | | 76 | L | U+004C | 4C | 拉丁大写字母 L | | 77 | M | U+004D | 4D | 拉丁大写字母 M | | 78 | N | U+004E | 4E | 拉丁大写字母 N | | 79 | O | U+004F | 4F | 拉丁大写字母 O | | 80 | P | U+0050 | 50 | 拉丁大写字母 P | | 81 | Q | U+0051 | 51 | 拉丁大写字母 Q | | 82 | R | U+0052 | 52 | 拉丁大写字母 R | | 83 | S | U+0053 | 53 | 拉丁大写字母 S | | 84 | T | U+0054 | 54 | 拉丁大写字母 T | | 85 | U | U+0055 | 55 | 拉丁大写字母 U | | 86 | V | U+0056 | 56 | 拉丁大写字母 V | | 87 | W | U+0057 | 57 | 拉丁大写字母 W | | 88 | X | U+0058 | 58 | 拉丁大写字母 X | | 89 | Y | U+0059 | 59 | 拉丁大写字母 Y | | 90 | Z | U+005A | 5A | 拉丁大写字母 Z | | 91 | ⟦ | U+27E6 | E2 9F A6 | 数学左白色方括号 | | 92 | ⧷ | U+29F7 | E2 A7 B7 | 带水平线的反斜线 | | 93 | ⟧ | U+27E7 | E2 9F A7 | 数学右白色方括号 | | 94 | ^ | U+005E | 5E | 抑扬音符 | | 95 | _ | U+005F | 5F | 下划线 | | 96 | ˋ | U+02CB | CB 8B | 修饰字母重音符 | | 97 | a | U+0061 | 61 | 拉丁小写字母 A | | 98 | b | U+0062 | 62 | 拉丁小写字母 B | | 99 | c | U+0063 | 63 | 拉丁小写字母 C | | 100 | d | U+0064 | 64 | 拉丁小写字母 D | | 101 | e | U+0065 | 65 | 拉丁小写字母 E | | 102 | f | U+0066 | 66 | 拉丁小写字母 F | | 103 | g | U+0067 | 67 | 拉丁小写字母 G | | 104 | h | U+0068 | 68 | 拉丁小写字母 H | | 105 | i | U+0069 | 69 | 拉丁小写字母 I | | 106 | j | U+006A | 6A | 拉丁小写字母 J | | 107 | k | U+006B | 6B | 拉丁小写字母 K | | 108 | l | U+006C | 6C | 拉丁小写字母 L | | 109 | m | U+006D | 6D | 拉丁小写字母 M | | 110 | n | U+006E | 6E | 拉丁小写字母 N | | 111 | o | U+006F | 6F | 拉丁小写字母 O | | 112 | p | U+0070 | 70 | 拉丁小写字母 P | | 113 | q | U+0071 | 71 | 拉丁小写字母 Q | | 114 | r | U+0072 | 72 | 拉丁小写字母 R | | 115 | s | U+0073 | 73 | 拉丁小写字母 S | | 116 | t | U+0074 | 74 | 拉丁小写字母 T | | 117 | u | U+0075 | 75 | 拉丁小写字母 U | | 118 | v | U+0076 | 76 | 拉丁小写字母 V | | 119 | w | U+0077 | 77 | 拉丁小写字母 W | | 120 | x | U+0078 | 78 | 拉丁小写字母 X | | 121 | y | U+0079 | 79 | 拉丁小写字母 Y | | 122 | z | U+007A | 7A | 拉丁小写字母 Z | | 123 | ❴ | U+2774 | E2 9D B4 | 中型左花括号装饰符 | | 124 | ∣ | U+2223 | E2 88 A3 | 除号 | | 125 | ❵ | U+2775 | E2 9D B5 | 中型右花括号装饰符 | | 126 | ˜ | U+02DC | CB 9C | 小型波浪号 | | 127 | ⌦ | U+2326 | E2 8C A6 | 向右擦除 | | 128 | ă | U+0103 | C4 83 | 带短音符号的拉丁小写字母 A | | 129 | Ă | U+0102 | C4 82 | 带短音符号的拉丁大写字母 A | | 130 | Ǎ | U+01CD | C7 8D | 带抑扬符号的拉丁大写字母 A | | 131 | ǟ | U+01DF | C7 9F | 带分音符和长音符号的拉丁小写字母 A | | 132 | Ǟ | U+01DE | C7 9E | 带分音符和长音符号的拉丁大写字母 A | | 133 | ȧ | U+0227 | C8 A7 | 带上点的拉丁小写字母 A | | 134 | Ȧ | U+0226 | C8 A6 | 带上点的拉丁大写字母 A | | 135 | ǡ | U+01E1 | C7 A1 | 带上点和长音符号的拉丁小写字母 A | | 136 | ƀ | U+0180 | C6 80 | 带笔划的拉丁小写字母 B | | 137 | Ƀ | U+0243 | C9 83 | 带笔划的拉丁大写字母 B | | 138 | Ɓ | U+0181 | C6 81 | 带钩的拉丁大写字母 B | | 139 | ƃ | U+0183 | C6 83 | 带顶条的拉丁小写字母 B | | 140 | Ƃ | U+0182 | C6 82 | 带顶条的拉丁大写字母 B | | 141 | ć | U+0107 | C4 87 | 带尖音符号的拉丁小写字母 C | | 142 | Ć | U+0106 | C4 86 | 带尖音符号的拉丁大写字母 C | | 143 | ĉ | U+0109 | C4 89 | 带抑扬符号的拉丁小写字母 C | | 144 | Ĉ | U+0108 | C4 88 | 带抑扬符号的拉丁大写字母 C | | 145 | č | U+010D | C4 8D | 带抑扬符号的拉丁小写字母 C | | 146 | Č | U+010C | C4 8C | 带抑扬符号的拉丁大写字母 C | | 147 | ċ | U+010B | C4 8B | 带上点的拉丁小写字母 C | | 148 | Ċ | U+010A | C4 8A | 带上点的拉丁大写字母 C | | 149 | ď | U+010F | C4 8F | 带抑扬符号的拉丁小写字母 D | | 150 | Ď | U+010E | C4 8E | 带抑扬符号的拉丁大写字母 D | | 151 | Đ | U+0110 | C4 90 | 带笔划的拉丁大写字母 D | | 152 | ȸ | U+0238 | C8 B8 | 拉丁小写字母 Db 双字母 | | 153 | Ɗ | U+018A | C6 8A | 带钩的拉丁大写字母 D | | 154 | ƌ | U+018C | C6 8C | 带顶条的拉丁小写字母 D | | 155 | Ƌ | U+018B | C6 8B | 带顶条的拉丁大写字母 D | | 156 | ȡ | U+0221 | C8 A1 | 带卷曲的拉丁小写字母 D | | 157 | ĕ | U+0115 | C4 95 | 带短音符号的拉丁小写字母 E | | 158 | Ĕ | U+0114 | C4 94 | 带短音符号的拉丁大写字母 E | | 159 | Ě | U+011A | C4 9A | 带抑扬符号的拉丁大写字母 E | | 160 | ė | U+0117 | C4 97 | 带上点的拉丁小写字母 E | | 161 | ȩ | U+0229 | C8 A9 | 带下加符的拉丁小写字母 E | | 162 | Ȩ | U+0228 | C8 A8 | 带下加符的拉丁大写字母 E | | 163 | ƒ | U+0192 | C6 92 | 带钩的拉丁小写字母 F | | 164 | Ƒ | U+0191 | C6 91 | 带钩的拉丁大写字母 F | | 165 | ǵ | U+01F5 | C7 B5 | 带尖音符号的拉丁小写字母 G | | 166 | Ǵ | U+01F4 | C7 B4 | 带尖音符号的拉丁大写字母 G | | 167 | ğ | U+011F | C4 9F | 带短音符号的拉丁小写字母 G | | 168 | Ğ | U+011E | C4 9E | 带短音符号的拉丁大写字母 G | | 169 | ǧ | U+01E7 | C7 A7 | 带抑扬符号的拉丁小写字母 G | | 170 | Ǧ | U+01E6 | C7 A6 | 带抑扬符号的拉丁大写字母 G | | 171 | ḡ | U+1E21 | E1 B8 A1 | 带长音符号的拉丁小写字母 G | | 172 | Ḡ | U+1E20 | E1 B8 A0 | 带长音符号的拉丁大写字母 G | | 173 | ĥ | U+0125 | C4 A5 | 带抑扬符号的拉丁小写字母 H | | 174 | Ĥ | U+0124 | C4 A4 | 带抑扬符号的拉丁大写字母 H | | 175 | ȟ | U+021F | C8 9F | 带抑扬符号的拉丁小写字母 H | | 176 | Ȟ | U+021E | C8 9E | 带抑扬符号的拉丁大写字母 H | | 177 | ƕ | U+0195 | C6 95 | 拉丁小写字母 Hv | | 178 | Ƕ | U+01F6 | C7 B6 | 拉丁大写字母 Hwair | | 179 | ĭ | U+012D | C4 AD | 带短音符号的拉丁小写字母 I | | 180 | Ĭ | U+012C | C4 AC | 带短音符号的拉丁大写字母 I | | 181 | Ǐ | U+01CF | C7 8F | 带抑扬符号的拉丁大写字母 I | | 182 | İ | U+0130 | C4 B0 | 带上点的拉丁大写字母 I | | 183 | ȉ | U+0209 | C8 89 | 带双沉音符号的拉丁小写字母 I | | 184 | ȋ | U+020B | C8 8B | 带倒短音符号的拉丁小写字母 I | | 185 | ĵ | U+0135 | C4 B5 | 带抑扬符号的拉丁小写字母 J | | 186 | Ĵ | U+0134 | C4 B4 | 带抑扬符号的拉丁大写字母 J | | 187 | ǰ | U+01F0 | C7 B0 | 带抑扬符号的拉丁小写字母 J | | 188 | ǩ | U+01E9 | C7 A9 | 带抑扬符号的拉丁小写字母 K | | 189 | Ǩ | U+01E8 | C7 A8 | 带抑扬符号的拉丁大写字母 K | | 190 | ķ | U+0137 | C4 B7 | 带下加符的拉丁小写字母 K | | 191 | Ķ | U+0136 | C4 B6 | 带下加符的拉丁大写字母 K | | 192 | ƙ | U+0199 | C6 99 | 带钩的拉丁小写字母 K | | 193 | Ƙ | U+0198 | C6 98 | 带钩的拉丁大写字母 K | | 194 | ĺ | U+013A | C4 BA | 带尖音符号的拉丁小写字母 L | | 195 | Ĺ | U+0139 | C4 B9 | 带尖音符号的拉丁大写字母 L | | 196 | ľ | U+013E | C4 BE | 带抑扬符号的拉丁小写字母 L | | 197 | Ľ | U+013D | C4 BD | 带抑扬符号的拉丁大写字母 L | | 198 | ƚ | U+019A | C6 9A | 带笔划的拉丁小写字母 L | | 199 | Ƚ | U+023D | C8 BD | 带笔划的拉丁大写字母 L | | 200 | Ń | U+0143 | C5 83 | 带尖音符号的拉丁大写字母 N | | 201 | ǹ | U+01F9 | C7 B9 | 带沉音符号的拉丁小写字母 N | | 202 | Ň | U+0147 | C5 87 | 带抑扬符号的拉丁大写字母 N | | 203 | ņ | U+0146 | C5 86 | 带下加符的拉丁小写字母 N | | 204 | Ņ | U+0145 | C5 85 | 带下加符的拉丁大写字母 N | | 205 | ȵ | U+0235 | C8 B5 | 带卷曲的拉丁小写字母 N | | 206 | ŏ | U+014F | C5 8F | 带短音符号的拉丁小写字母 O | | 207 | Ŏ | U+014E | C5 8E | 带短音符号的拉丁大写字母 O | | 208 | Ǒ | U+01D1 | C7 91 | 带抑扬符号的拉丁大写字母 O | | 209 | ȫ | U+022B | C8 AB | 带分音符和长音符号的拉丁小写字母 O | | 210 | Ȫ | U+022A | C8 AA | 带分音符和长音符号的拉丁大写字母 O | | 211 | ȱ | U+0231 | C8 B1 | 带上点和长音符号的拉丁小写字母 O | | 212 | ƥ | U+01A5 | C6 A5 | 带钩的拉丁小写字母 P | | 213 | Ƥ | U+01A4 | C6 A4 | 带钩的拉丁大写字母 P | | 214 | ȹ | U+0239 | C8 B9 | 拉丁小写字母 Qp 双字母 | | 215 | ɋ | U+024B | C9 8B | 带钩尾的拉丁小写字母 Q | | 216 | ŕ | U+0155 | C5 95 | 带尖音符号的拉丁小写字母 R | | 217 | Ŕ | U+0154 | C5 94 | 带尖音符号的拉丁大写字母 R | | 218 | ř | U+0159 | C5 99 | 带抑扬符号的拉丁小写字母 R | | 219 | Ř | U+0158 | C5 98 | 带抑扬符号的拉丁大写字母 R | | 220 | ŗ | U+0157 | C5 97 | 带下加符的拉丁小写字母 R | | 221 | Ŗ | U+0156 | C5 96 | 带下加符的拉丁大写字母 R | | 222 | ś | U+015B | C5 9B | 带尖音符号的拉丁小写字母 S | | 223 | Ś | U+015A | C5 9A | 带尖音符号的拉丁大写字母 S | | 224 | š | U+0161 | C5 A1 | 带抑扬符号的拉丁小写字母 S | | 225 | Š | U+0160 | C5 A0 | 带抑扬符号的拉丁大写字母 S | | 226 | ş | U+015F | C5 9F | 带下加符的拉丁小写字母 S | | 227 | Ş | U+015E | C5 9E | 带下加符的拉丁大写字母 S | | 228 | ť | U+0165 | C5 A5 | 带抑扬符号的拉丁小写字母 T | | 229 | Ť | U+0164 | C5 A4 | 带抑扬符号的拉丁大写字母 T | | 230 | ţ | U+0163 | C5 A3 | 带下加符的拉丁小写字母 T | | 231 | Ţ | U+0162 | C5 A2 | 带下加符的拉丁大写字母 T | | 232 | ț | U+021B | C8 9B | 带下逗号的拉丁小写字母 T | | 233 | Ț | U+021A | C8 9A | 带下逗号的拉丁大写字母 T | | 234 | ŭ | U+016D | C5 AD | 带短音符号的拉丁小写字母 U | | 235 | Ŭ | U+016C | C5 AC | 带短音符号的拉丁大写字母 U | | 236 | Ǔ | U+01D3 | C7 93 | 带抑扬符号的拉丁大写字母 U | | 237 | ű | U+0171 | C5 B1 | 带双尖音符号的拉丁小写字母 U | | 238 | ȕ | U+0215 | C8 95 | 带双沉音符号的拉丁小写字母 U | | 239 | Ʉ | U+0244 | C9 84 | 拉丁大写字母 U Bar | | 240 | Ṿ | U+1E7E | E1 B9 BE | 带下点的拉丁大写字母 V | | 241 | Ʋ | U+01B2 | C6 B2 | 带钩的拉丁大写字母 V | | 242 | ŵ | U+0175 | C5 B5 | 带抑扬符号的拉丁小写字母 W | | 243 | Ŵ | U+0174 | C5 B4 | 带抑扬符号的拉丁大写字母 W | | 244 | ŷ | U+0177 | C5 B7 | 带抑扬符号的拉丁小写字母 Y | | 245 | Ŷ | U+0176 | C5 B6 | 带抑扬符号的拉丁大写字母 Y | | 246 | Ÿ | U+0178 | C5 B8 | 带分音符的拉丁大写字母 Y | | 247 | ȳ | U+0233 | C8 B3 | 带长音符号的拉丁小写字母 Y | | 248 | ƴ | U+01B4 | C6 B4 | 带钩的拉丁小写字母 Y | | 249 | Ƴ | U+01B3 | C6 B3 | 带钩的拉丁大写字母 Y | | 250 | ź | U+017A | C5 BA | 带尖音符号的拉丁小写字母 Z | | 251 | Ź | U+0179 | C5 B9 | 带尖音符号的拉丁大写字母 Z | | 252 | ž | U+017E | C5 BE | 带抑扬符号的拉丁小写字母 Z | | 253 | Ž | U+017D | C5 BD | 带抑扬符号的拉丁大写字母 Z | | 254 | ż | U+017C | C5 BC | 带上点的拉丁小写字母 Z | | 255 | Ż | U+017B | C5 BB | 带上点的拉丁大写字母 Z | 此实现使用一组精心选择的 UTF-8 字符来表示每个可能的字节值: - 控制字符 (0-31) 使用视觉上独特的符号,主要来自数学符号、箭头和拉丁文扩展等 Unicode 区块 - 标准可打印 ASCII 字符 (33-126, 除 ", ', 和 \\ 外) 保持原样 - 特殊字符(空格、双引号、单引号、反斜杠)获得更可见的表示形式 - 扩展字节 (128-255) 由 `character_map.txt` 驱动,并按字母顺序排列,以使相邻字形在视觉上相关 ### 编码/解码映射表 实现会在初始化时构建两个查找表: - `encode_map`:将字节值 (0-255) 映射到它们的 UTF-8 字符串表示形式 - `decode_map`:将 UTF-8 字符串表示形式映射回字节值 这些双向映射确保了两个方向上高效且准确的转换。 ## 许可证 本项目采用 MIT 许可证 - 详情请参阅 LICENSE 文件。
标签:ASCII, CMS安全, GNU通用公共许可证, JavaScript, LuaJIT, MITM代理, Node.js, UTF-8, WebAssembly, Zig, 二进制数据, 二进制编码, 人类可读, 反序列化器, 客户端加密, 序列化器, 拖放界面, 数据共享, 数据可视化, 数据序列化, 数据编码工具, 日志, 终端兼容, 编码, 解码