Base84 值得在文件名中占有一席之地

Lobsters Hottest 工具

摘要

Base84 是一种用于文件系统安全文件名的新编码方案,在 Unix、macOS 和 Windows 上提供可移植且高效的编码,并且与 Base64 或 Base91 等替代方案相比,具有改进的比特打包。

<p><a href="https://lobste.rs/s/bfiose/base84_deserves_place_file_names">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/09/12 16:39

# Base84 应在文件名中占有一席之地 来源:https://00f.net/2026/09/09/base84/ TurboCrypt (https://github.com/jedisct1/turbocrypt) 文件加密工具最初是为 Unix 系统设计的。 它曾使用 Base91 来加密文件名并编码生成的密文。 为何选择 Base91?因为它非常适合加密的文件名,生成的字符串可以在 Unix 和 macOS 上作为有效文件存储。 “但我的文件系统可以存储任意文件名!” 对某些文件系统来说可能是真的,但这是在未考虑库和应用程序的情况下。例如,macOS 的访达(Finder)会完全不喜欢这样。 因此,Base91 对于加密的文件和目录名运行良好。 然后人们要求 Windows 支持,而 Unix 文件系统安全字母表中的若干字符在 Windows 上是禁止使用的。 于是,TurboCrypt 决定改用 Base84。 令人惊讶的是,Base84 似乎并未在任何地方被定义或使用,尽管它对于任何应被编码为可移植文件系统安全名称的内容都完美适用。 ## 为何选择 Base84? 除了空格,有 94 个可打印的 ASCII 字符。但 Windows 规则排除了其中九个: 因此剩下 85 个。 但以点结尾的名称无法可靠地通过 Windows shell 和普通文件 API 使用。 同样去掉点号,我们就得到了 84 个可以在文件名任何位置出现的字符。Microsoft 记录了这些限制 (https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file)。 然而,Windows 允许以点开头:`.gitignore` 是可以的。 但去掉点号也可以避免 Unix 上的隐藏名称以及特殊名称 `.` 和 `..`。 以下是字母表,按编码顺序排列: ``` ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'()+,-;=@[]^_`{}~ ``` 每个字符在通常的 Linux、macOS 和 Windows 文件系统上都是文件名中的有效字符。 ## 打包比特 zig-base84 (https://github.com/jedisct1/zig-base84) 是 Base84 的一种实现。 它输出五字符为一组。五是一个理想的平衡点:`84^5 = 4,182,119,424`,仅比 `2^32` 少 2.6%。 这为一组数据在均匀随机输入下,约 95% 的时间能容纳 32 位,其余时间容纳 31 位提供了足够的空间。 编码器查看接下来的 31 位。如果其值低于 `84^5 - 2^31`,则有空间容纳第 32 位。否则,它仅消耗这 31 位。无论哪种情况,该值都能装入五个 base-84 数字中。 在随机输入下,这相当于每组约 31.95 位,或每字符 6.39 位。输出比二进制输入大约 25.2%。这几乎接近 Base85 的效率。 这些扩展率忽略了最后不足一组的部分;平均值假设为随机输入: 编码方式 | 平均扩展率 | 最坏情况扩展率 --- | --- | --- Base64 | 33.3% | 33.3% Base84 | 25.2% | 29.0% 一个全由 `0xff` 填充的输入会迫使每个完整组只消耗 31 位。这是最坏的情况:约 29% 的扩展率。 大多数文件系统将名称限制为 255 字节。由于字母表是 ASCII 编码,那就是 255 个字符。五能整除 255,因此即使是最大长度的名称也只包含完整的组,不会有比特损失于部分组。Base84 保证能容纳 197 字节的输入,而未填充的 Base64 只能容纳 191 字节。 ## 仅限 Unix 的名称 Unix 文件名可以包含许多 Windows 拒绝的标点符号。NUL 和 `/` 在文件名内部是禁止的;Linux 路径名文档 (https://www.man7.org/linux/man-pages/man7/pathname.7.html) 列出了规则和特定文件系统的限制。 zig-base91 (https://github.com/jedisct1/zig-base91) 中的 `filesystem` 变体将标准 Base91 字母表中的斜杠替换为撇号。在随机输入下,它每字符打包约 6.51 位,扩展率约为 23%。 对于仅限 Unix 的名称,请使用该变体。标准 Base91 仍然包含 `/`,并且两个字母表都包含 Windows 拒绝的字符。 ## 保留名称和大小写 Windows 保留设备名称,如 `CON`、`NUL` 和 `COM1`,不区分大小写。 五字符分组有一个有用的副作用:使用标准字母表时,编码器无法拼写出保留的设备名称,即使对于短输入也是如此。 三字符输出总是以 `A` 到 `J` 结尾。这排除了 `CON`、`PRN`、`AUX` 和 `NUL`,不区分大小写。 四字符输出总是以大写字母或 `a`、`b`、`c` 结尾。它不能以数字结尾,因此 `COM1` 到 `COM9` 和 `LPT1` 到 `LPT9` 也是不可能的。Windows 也保留的上标数字不在字母表中。 而且字母表中没有点号,因此保留名称后跟扩展名也是不可能的。 无需填充或特殊处理来避免这些名称。

相似文章

文件名的Unicode组合

Lobsters Hottest

本文讨论了在Subversion版本控制系统中,不同操作系统之间Unicode文件名组合(NFC与NFD)面临的挑战,并提出了处理这些差异的解决方案。

bijou64:一种可变长度整数编码

Lobsters Hottest

bijou64是一种新的可变长度整数编码,确保规范表示,解决了签名验证错误,并且比常见的LEB128编码快数倍。

UTF-8000:无限制的UTF-8

Hacker News Top

UTF-8000 是对UTF-8的一个提议扩展,允许任意大的编码单元,同时保留UTF-8的特性,作为一个独立项目呈现,并附有参考实现。

二进制文件可视化

Hacker News Top

本文描述了在 'bine' 十六进制编辑器中增强的二进制文件可视化功能的开发,包括使用 Unicode 字符的彩色输出和一种将二进制文件解释为图像以进行大规模查看的方法。