Python 将字符串可逆编码为unix文件名

Python 将字符串可逆编码为unix文件名,python,linux,python-3.x,encoding,filenames,Python,Linux,Python 3.x,Encoding,Filenames,有没有办法将任意用户输入的名称转换为具有可逆编码的安全文件名 我有一些属于用户命名的实体的数据文件。当然,他们可以做一些愚蠢的事情,比如在名称中添加无效的文件系统字符 我经常看到的两个建议是: A) Base64编码它们 B) 删除非法字符 Base64是可逆的,但是对于调试/内省来说,当文件名看起来尽可能像文件名时,它真的很好。只是让一切都更易于调试。方法B是不可逆的,因此“实际”名称无论如何都必须冗余存储,因此不只是使用uuid或其他东西没有实际价值 这是专门针对Linux的。虽然这不是py

有没有办法将任意用户输入的名称转换为具有可逆编码的安全文件名

我有一些属于用户命名的实体的数据文件。当然,他们可以做一些愚蠢的事情,比如在名称中添加无效的文件系统字符

我经常看到的两个建议是:

A) Base64编码它们

B) 删除非法字符

Base64是可逆的,但是对于调试/内省来说,当文件名看起来尽可能像文件名时,它真的很好。只是让一切都更易于调试。方法B是不可逆的,因此“实际”名称无论如何都必须冗余存储,因此不只是使用uuid或其他东西没有实际价值


这是专门针对Linux的。虽然这不是python特有的,但这正是我实现它的目的。

您可以使用URL编码:

from urllib.parse import quote

safefilename = quote(filename, safe='')
这是完全可折叠的,并保持ASCII字符的可读性:

>>> from urllib.parse import quote, unquote
>>> quote('foo/../bar', safe='')
'foo%2F..%2Fbar'
>>> unquote(quote('foo/../bar', safe=''))
'foo/../bar'

safe
设置为空字符串;默认值为
“/”
,因此斜杠通常不会转义。

您可以使用URL编码:

from urllib.parse import quote

safefilename = quote(filename, safe='')
这是完全可折叠的,并保持ASCII字符的可读性:

>>> from urllib.parse import quote, unquote
>>> quote('foo/../bar', safe='')
'foo%2F..%2Fbar'
>>> unquote(quote('foo/../bar', safe=''))
'foo/../bar'

safe
设置为空字符串;默认值为
“/”
,因此斜杠通常不会转义。

您可以对用户提供的字符串进行URL编码

根据(其本身引用RFC3986),唯一的URL安全字符是A-Z、A-Z、0-9、破折号、下划线、点和波浪号(~)。Tilde在shell中有一个独特的解释,但对于Linux文件名来说并不违法

看起来URL编码在使用urllib(2)的Python中非常容易,但我不是Python程序员


请参阅:

您可以对用户提供的字符串进行URL编码

根据(其本身引用RFC3986),唯一的URL安全字符是A-Z、A-Z、0-9、破折号、下划线、点和波浪号(~)。Tilde在shell中有一个独特的解释,但对于Linux文件名来说并不违法

看起来URL编码在使用urllib(2)的Python中非常容易,但我不是Python程序员


请参阅:

什么是安全的?数据库插入、网络传输、不被窥视?可安全用作合法文件名。例如,文件名不能包含“/”字符。Python具有字符串的
ascii()
表示,或者可以使用
unicode\u escape
显式编码,将任何非ascii码点转换为转义码。可读性仍然很强。所以你想接受可能包含路径分隔符或其他非法字符的任意文件名,并使其可用作文件名?安全原因是什么?数据库插入、网络传输、不被窥视?可安全用作合法文件名。例如,文件名不能包含“/”字符。Python具有字符串的
ascii()
表示,或者可以使用
unicode\u escape
显式编码,将任何非ascii码点转换为转义码。可读性仍然很强。因此,您希望接受可能包含路径分隔符或其他非法字符的任意文件名,并使其可用作文件名?类似但自定义的方案可能更有用(例如,保持非ASCII字符易读)。可能对少数非法字符进行百分比编码,并按原样粘贴其余字符(如UTF-8)。这需要付出更多的努力,但可能是值得的。@delnan:问题在于它取决于文件系统什么是合法的,什么是非法的。例如,HFS+将
转换为
/
,因此您通常不希望文件名中包含
s。其他文件系统有不同的限制。@delnan:所以,如果没有安全列表,我会选择一个小的子集。不过,URL引用是一个简单的解决方法。很好。另一方面,由于几乎每个文件系统的元字符都在ASCII范围内,并且多字节代码点会给出特别难看的转义序列,因此我仍然会尝试通过未更改的方式走私大于127的代码点。但是,Linux的文件名限制不是255字节吗。对于长URL,如果这样的编码方案仍然可能导致过长的无效文件名,您该怎么办?如果URL是可逆的,有没有办法获得有效的文件名?类似但自定义的方案可能更有用(例如,保持非ASCII字符易读)。可能对少数非法字符进行百分比编码,并按原样粘贴其余字符(如UTF-8)。这需要付出更多的努力,但可能是值得的。@delnan:问题在于它取决于文件系统什么是合法的,什么是非法的。例如,HFS+将
转换为
/
,因此您通常不希望文件名中包含
s。其他文件系统有不同的限制。@delnan:所以,如果没有安全列表,我会选择一个小的子集。不过,URL引用是一个简单的解决方法。很好。另一方面,由于几乎每个文件系统的元字符都在ASCII范围内,并且多字节代码点会给出特别难看的转义序列,因此我仍然会尝试通过未更改的方式走私大于127的代码点。但是,Linux的文件名限制不是255字节吗。对于长URL,如果这样的编码方案仍然可能导致过长的无效文件名,您该怎么办?如果URL是可逆的,有没有办法获得有效的文件名?