Windows 使用 Unicode 私有使用区域 0xf000 到 0xf0ff 中的字符作为对 Linux 文件名中合法但 Windows 中不合法的字符进行编码的方式。这些可以来自适用于 Linux 的 Windows 子系统,或者如果您在不同操作系统上使用网络工具和/或外部磁盘(例如,与 MacOSX 一起使用的 FAT32 磁盘),则可以从各种来源复制/创建文件。当您想要从 WSL 和 Windows(例如使用 python)访问这些文件时,问题是您需要知道映射是什么,但我找不到明确的表。 WSL 的一些实验表明,从 WSL 到 Windows 的映射如下:
< U+f03c
> U+f03e
: U+f03a
" U+f022
\ U+f05c
| U+f07c
? U+f03f
* U+f02a
但是通过窥探我的 Windows 文件发现了这个范围内的更多代码点,但我无法找出它们映射到的内容。到目前为止我最好的猜测(基于上下文)是
U+f009 - tab
U+f00a - linefeed
U+f00d - carriage return
U+f020 - double quote
U+f021 - vertical line
U+f022 - colon or solidus
U+f023 - less than sign
U+f024 - greater than sign
U+f025 - question mark
U+f026 - reverse solidus
U+f027 - vertical line
U+f028 - space [at end of filename]
U+f029 - full stop [at end of filename]
我的猜测是,在 Microsoft 文档的深处有一个映射列表(或者至少是推荐的映射)。或者也许随着时间的推移,制作跨平台工具的不同人已经提出了自己的映射。我希望有人能给我指出这些信息的一些来源。
一旦我更好地了解了应该使用什么映射,我的计划就是编写一个统一所有这些的 python 程序(或者至少识别文件,以便我可以弄清楚要做什么)。我可能会重命名所有文件,以便这些字符都映射到它们的全角等效字符,因为这在我的所有文件系统上都是可识别的(但很难看)。到目前为止我的代码是这样的:
map_dict = {
0xf009:'\uff3ct', # tab
0xf00a:'\uff3cn', # linefeed
0xf00d:'\uff3cr', # carriage return
0xf020:'\uff02', # double quote
0xf021:'\uff5c', # vertical line
0xf022:'\uff1a', # colon or solidus
0xf023:'\uff1c', # less than sign
0xf024:'\uff1e', # more than sign
0xf025:'\uff1f', # question mark
0xf026:'\uff3c', # reverse solidus
0xf027:'\uff5c', # vertical line
0xf028:' ', # this seems to be at the end of the filename
0xf029:'.', # this seems to be at the end of the filename
0xf03a:'\uff1a', # colon
0xf03f:'\uff1f', # question mark
0xf8ff:'Apple\u2122', # Apple trade mark
}
def map_filename(input_name, map_dict):
output_name = ""
mapped = False
for c in str(input_name):
code_point = ord(c)
if code_point in map_dict:
output_name += map_dict[code_point]
mapped = True
else:
if ((code_point >= 0xe000 and code_point <= 0xf8ff)
or (code_point >= 0xf0000 and code_point <= 0xfffff)
or (code_point >= 0x100000 and code_point <= 0x10ffff)):
print('Error "%s" contains unmapped private use character %04x' % (input_name, code_point))
sys.exit(1)
output_name += c
return (output_name, mapped)
然而,这完全是猜测,并且存在很多漏洞。必须有 WSL 如何映射所有不寻常字符的列表,以及 MacOS 或 Linux 如何在 FAT32 磁盘和其他地方编码其非 Windows 字符的列表。
不是明确的答案,而是猜测:它似乎是 U+F000 加上 ASCII 等效值。因此,查找在 NTFS 中无效的每个 ASCII 字符,然后将 U+F000 添加到其中,然后中提琴!你的一些猜测不符合这个计划,但大多数都符合。