如何在Ruby中可逆地转义URL,以便将其保存到文件系统中

如何在Ruby中可逆地转义URL,以便将其保存到文件系统中,ruby,string,file,Ruby,String,File,用例示例保存http://example.com作为计算机上的文件名,但转义了不安全字符(即:和/) 经典的方法是使用正则表达式去掉所有非字母数字的破折号下划线字符,但这样就不可能将文件名反转为URL。是否有一种方法(可能是结合CGI.escape和另一个过滤器)来清理Windows和*nix的文件名?即使折衷是一个更长的文件名 编辑: 带有CGI.escape的示例 CGI.escape 'http://www.example.com/Hey/whatsup/1 2 3.html#hash'

用例示例保存
http://example.com
作为计算机上的文件名,但转义了不安全字符(即
/

经典的方法是使用正则表达式去掉所有非字母数字的破折号下划线字符,但这样就不可能将文件名反转为URL。是否有一种方法(可能是结合
CGI.escape
和另一个过滤器)来清理Windows和*nix的文件名?即使折衷是一个更长的文件名

编辑:

带有
CGI.escape的示例

 CGI.escape 'http://www.example.com/Hey/whatsup/1 2 3.html#hash'
 #=> "http%3A%2F%2Fwww.example.com%2FHey%2Fwhatsup%2F1+2+3.html%23hash"
有几件事,
%
符号作为文件字符是否完全安全?不幸的是,
CGI.escape
不会在第一次传递时将格式错误的URL中的空格转换为
%20
,因此我认为任何转换方法都需要使用
gsub
将所有空格更改为
+
,然后应用
CGI.escape

,其中一种方法是对文件名进行哈希运算。例如,此问题的URL为:
https://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste
。您可以使用Ruby标准库的
摘要/md5
库来散列名称。朴素典雅

 CGI.escape 'http://www.example.com/Hey/whatsup/1 2 3.html#hash'
 #=> "http%3A%2F%2Fwww.example.com%2FHey%2Fwhatsup%2F1+2+3.html%23hash"
require "digest/md5"

foldername = "https://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste"
hashed_name = Digest::MD5.hexdigest(foldername) # => "5045cccd83a8d4d5c4fc01f7b4d8c502"
该方案的推论是,MD5哈希用于验证下载的真实性/完整性,因为出于所有实际目的,字符串的MD5摘要总是返回相同的十六进制字符串

然而,我不会称之为“可逆”。您需要有一种自定义的方法来查找生成的每个哈希的URL。可能是包含该数据的
.yml
文件


更新:正如所建议的,当有大量文件需要存储时,简单的SQLite db比
.yml
文件要好得多。

其中一种方法是对文件名进行“散列”。例如,此问题的URL为:
https://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste
。您可以使用Ruby标准库的
摘要/md5
库来散列名称。朴素典雅

require "digest/md5"

foldername = "https://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste"
hashed_name = Digest::MD5.hexdigest(foldername) # => "5045cccd83a8d4d5c4fc01f7b4d8c502"
该方案的推论是,MD5哈希用于验证下载的真实性/完整性,因为出于所有实际目的,字符串的MD5摘要总是返回相同的十六进制字符串

然而,我不会称之为“可逆”。您需要有一种自定义的方法来查找生成的每个哈希的URL。可能是包含该数据的
.yml
文件


更新:正如所建议的,当有大量文件需要存储时,一个简单的SQLite db会比一个
.yml
文件好得多。

下面是我将如何做的(根据需要调整正则表达式):

编辑:

如果结果文件名的长度是一个问题,那么我会将文件存储在子目录中,并使用与url路径段相同的名称。

以下是我将如何操作(根据需要调整正则表达式):

编辑:


如果结果文件名的长度是一个问题,那么我会将文件存储在与url路径段同名的子目录中。

url编码url如何?将字符转换为
%XX
。我将在问题中添加一个示例,以澄清情况……但我不确定%符号在主要操作系统中是否安全。鉴于文件名长度限制,这是一项非常具有挑战性(不可能)的任务。仅当您想要处理最极端的边缘情况时,这是不可能的。但是,不应该不可能找到一个函数(我希望它在stdlib中的某个地方,但显然不是)来进行翻译,并让客户机来处理文件长度限制。例如,客户机可能决定将url存储在相应的子目录中:编写自己的url转义函数,并使用其他函数,而不是
%
。比如,一个下划线。url编码url如何?将字符转换为
%XX
。我将在问题中添加一个示例,以澄清情况……但我不确定%符号在主要操作系统中是否安全。鉴于文件名长度限制,这是一项非常具有挑战性(不可能)的任务。仅当您想要处理最极端的边缘情况时,这是不可能的。但是,不应该不可能找到一个函数(我希望它在stdlib中的某个地方,但显然不是)来进行翻译,并让客户机来处理文件长度限制。例如,客户机可能决定将url存储在相应的子目录中:编写自己的url转义函数,并使用其他函数,而不是
%
。比如,下划线。我建议也使用MD5。使用YAML文件是不可维护或可扩展的。相反,一个小的SQLite数据库会非常好。它会围绕YAML运行,因为它允许索引和随机访问。不利的一面是,如果数据库被破坏或删除,文件名就会丢失。@theTinMan您是否刚刚否决了一个以可伸缩性为名的想法,然后建议使用sqlite作为替代方案?只要您保持记录有序(哈希值基本上是非顺序序列号),任何磁盘文件格式都可以。最糟糕的情况是,您可能必须对反向查找文件进行分段。对于某些用例,MD5哈希绝对是一种解决方案。然而,在某些特定的用例中,让文件名可以识别是很有帮助的(尽管有%的符号)…使用哈希函数,无论其可逆性如何,都不可能引起注意。YAML将不可扩展,因为每次修改文件时都必须对其进行完整的解析和重写。这样做的开销将高于eq