0

我们正在使用许多基于 unix 的文件系统,所有这些文件系统都有一组类似的限制,即某些字符不能在用户名字段中使用。这些限制之一是没有“@”、“_”或“。” 在名字中。作为 unix,还有许多其他限制。

所以问题是是否有一种众所周知的算法可以获取电子邮件地址并将其转换为可预测的 unix 文件名。我们需要在某个时候扭转这一点才能收到电子邮件。

我考虑过做类似“.”->“DOT”、“@”->“AT”等的事情。但是有大小限制和其他通常有问题的事情。我还可以通过将电子邮件的@xyz.com 部分映射到特殊字符或其他内容来进行优化。每个实现最多只有 3 个需要支持的域。我希望有人在没有大量权衡的情况下找到了解决方案。

更新: - 两个目标文件系统是 AFS 和 NFS。

-Base64 不起作用,因为它没有兼容的字符。“/”

-可读性更好。

似乎最好的答案是将@xyz.com 域替换为单个非标准字符,然后具有可以将名称的第一部分缩小为适合各种文件系统的用户名长度限制的功能. 但是有什么好的功能呢?

4

4 回答 4

2

您可以尝试用于 URI 的 URL 百分比 (%) 编码方案的修改版本。

如果您的特定文件系统上不允许使用百分比符号,只需将其替换为不同的允许字符(并记住正确编码该字符的任何出现)。

使用这种方法: mail.address@server.com

会成为: mail%2Eaddress%40server%2Ecom

或者,如果您必须替换(例如)字母a而不是%符号: ma61ila2Ea61ddressa40servera2Ecom

也许不完全是人类可读的,但通过编码算法很容易处理。为了获得最佳的空间效率,您的转义字符应该是文件系统允许的字符,但不太可能经常出现在地址中。

这种编码方案的优点是大多数普通字符不会增加大小。字符串长度只会增加文件系统不支持的字符。

于 2011-08-24T21:04:52.813 回答
1

查看 base64。编码和解码定义明确。我更喜欢这个而不是任何一天滚动我自己的格式。

于 2011-08-24T21:11:09.300 回答
0

嗯,从你的问题来看,我在这一点上并不完全清楚,但既然你想要一些转换,我假设你想要至少是人类可读的东西?

每个操作系统可能有不同的限制,但您是否足够接近平台,以便能够找出/测试用户名中可接受的内容?如果你能找到三个“特殊”字符,你可以用它们来替换'@', '.', '_' 你会很高兴。(那是全面的吗?如果不是,你需要确保你知道所有这些,否则你可能会发生冲突。)我搜索了一下,试图找到是否有 POSIX 标准,但找不到任何东西,所以这就是为什么我认为,如果您可以测试什么是有效的,那将是最直接的途径。

即使有一个特殊字符,您也可以进行 URL 编码,如果可用,则使用 '%',或者如果不可用,则使用任何您选择的字符,例如 '!",然后{ '@'->'!40", '_'->'!5F', '.'-> '!2E' }。(规范 [RFC1738] http://www.rfc-editor .org/rfc/rfc1738.txt)将字符定义为 US-ASCII 所以你可以找到一个表格,例如在维基百科的 ASCII 文章中并在那里查找正确的十六进制数字。)或者,你可以自己做简单的映射,因为你不需要整个 ASCII 集,你可以做一个每个转义字符有两个字符的映射,并且有,比如说,'!a','!u','!p'at,下划线,句点。

如果您有两个特殊字符,例如 '%' 和 '!',您可以分隔代表字符的文本,例如%at!,&us!'&pd!'。(这几乎是 html 样式的编码,但不是 '&' 和 ';' 您使用的是可用的,并且您正在编写自己的助记符。)另一个想法是您可以使用符号运行来确定翻译的字符,其中每个新字符都会翻转正在使用的符号。(如果我们需要将两个不允许的字符并排放置,这可以方便地停止运行。)因此假设 '%' 和 '!',句点为 1,下划线为 2,at-sign 为 3,'mickey._sample_@fake.out'将变为'mickey%!!sample%%!!!fake%out'. 还有其他变体,但这个很容易编码。

如果这些都不是一个选项(例如,根本没有符号,只有 [a-zA-Z0-9]),那么我真的认为 Base64 的答案听起来是正确的。真的,一旦我们得到除了简单替换(甚至那个)之外的任何东西,如果这是目标,那么输入已经变得困难了。但是如果你真的需要尽量保持电子邮件的可读性,你要做的就是实现某种转义。我想用'0'作为你的转义字符,所以现在'0'变成'00','@'变成'01','.' 变成“02”,“_”变成“03”。所以现在,'mickey01._sample_@fake.out'会变成'mickey0010203sample0301fake02out'. 不漂亮,但应该可以;因为我们转义了任何原始 0,所以请始终确保为您选择作为转义字符的任何内容定义一个映射,您应该没问题..

这就是我能想到的atm。:) 当然,如果这些用户名不需要在原始文件中可读,那么显然 Base64 似乎不起作用,因为它会产生斜杠。哎呀,好吧,只是每个字符的 2 位 US-ASCII 十六进制值,你就完成了……] 是一个好方法;那里有很多经过调试的、经过大量现场测试的代码,它可以很方便地解决您的问题。:)

于 2011-08-24T22:40:21.737 回答
0

鉴于...
  - 各种文件系统中允许的有限字符集
  - 希望保持编码的电子邮件地址简短(为了人类可读性和文件系统限制的可能问题)
......可能的方法可能是两个步骤电子邮件的编码逻辑

  • 首先使用无损压缩算法(如 Lempel-Ziv)进行压缩,有效地将其转换为“二进制”形式,存储在较短的字节数组中
  • 然后使用类似 Base64 的算法对这个字节数组进行编码

这个想法是最小化二进制表示的大小,以便与编码的存储效率低下相关的扩展 - 每个字符只能存储大约 6 位(并且可能更少),不会导致编码字符串太长了。
在没有对压缩和编码过于复杂的情况下,这样的系统可能会生成可能是输入字符串大小(电子邮件地址)的 4/5 的编码字符串:压缩应该很容易缩小一半,但是编码,比如 Base32 ,将使二进制形式的大小增加 8/5。

提高压缩率的努力可能允许选择更“浪费”的编码方案(具有更小的字符集),这可能有助于使输出更易于阅读,并且在各种文件系统上也更安全。例如,Base64 似乎是最佳的。在空间方面,仅使用大写字母(以 26 为基数)可以确保底层方案对文件名不区分大小写的文件系统的可移植性。
初始通用压缩的另一个好处是,几乎不需要对有效输入键(此处为电子邮件地址)的语法做出假设(如果有的话)。

压缩思路
LZ 似乎是一个不错的选择,'尽管人们可能会考虑使用电子邮件地址中常见的模式(例如“.com”甚至“a.com”、“b.com”等)为其初始缓冲区进行 primin。
该初始缓冲区将确保每个压缩电子邮件地址有多个“引用”实例,因此总体上具有更好的压缩率)。为了进一步压缩几个字节,也许可以使用 LZH 或其他 LZ 变体。
除了上面提到的缓冲区启动之外,另一个定制可能是使用比典型 LZ 算法更短的缓冲区,因为我们必须压缩的字符串(电子邮件地址实例)本身非常短,并且不会从 512 字节缓冲区中受益. (更短的缓冲区大小允许引用更短的代码)

编码思路
Base64不适合原样,因为斜线 (/)、加号 (+) 和等号 (=) 字符。可以使用替代字符来替换这些字符;我想到了破折号 (-),但是找到目标文件系统的所有“风格”都允许的三个字符可能有点困难。
尽管如此,Base64 及其每 3 个有效负载字节的 4 个输出字符的比率提供了可能几乎无法实现的存储效率上限[对于可接受的字符集]。
在这种效率的低端,可能是数组中字节的十六进制值的 ASCII 表示. 这种将有效负载字节加倍的格式在长度上是可以接受的,并且由于其简单性(输入中的每个半字节(4 位)与编码字符串中的字符之间存在直接而简单的关系)而有趣
。Base32其中 A 到 Z 分别编码 0 到 25 和 0 到 5 编码 26 到 31,基本上 Base64 的变体,每 5 个有效负载字节比率 8 个输出字符可能是一个非常可行的折衷方案。

于 2011-08-24T23:54:16.443 回答