在查看URL安全base 64编码时,我发现它是一个非常非标准的东西。尽管PHP拥有大量内置函数,但没有一个用于URL安全base 64编码。在base64_encode()
的手册页上,大多数评论建议使用该功能,包含strtr()
:
function base64_url_encode($input)
{
return strtr(base64_encode($input), '+/=', '-_,');
}
我在这个区域找到的唯一Perl模块是MIME::Base64::URLSafe(source),它在内部执行以下替换:
sub encode ($) {
my $data = encode_base64($_[0], '');
$data =~ tr|+/=|\-_|d;
return $data;
}
与上面的PHP函数不同,这个Perl版本完全删除'='(等于)字符,而不是像PHP那样用','(逗号)替换它。 Equals是一个填充字符,因此Perl模块在解码时根据需要替换它们,但这种差异使得两个实现不兼容。
最后,Python函数urlsafe_b64encode(s)保持'='填充,提示有人提出this function以删除在'python base64 url safe'的Google结果中突出显示的填充:
from base64 import urlsafe_b64encode, urlsafe_b64decode
def uri_b64encode(s):
return urlsafe_b64encode(s).strip('=')
def uri_b64decode(s):
return urlsafe_b64decode(s + '=' * (4 - len(s) % 4))
这里的愿望是拥有一个字符串,该字符串可以包含在URL中而无需进一步编码,因此字符'+','/'和'='的切换或翻译。由于没有明确的标准,什么是正确的方法?
答案 0 :(得分:9)
似乎有一个标准,它是RFC 3548,第4节, Base 64编码,带有URL和文件名安全字母:
此编码在技术上是相同的 到了前一个,除了 62:nd和63:rd字母字符,如 如表2所示。
+
和/
应分别由- (minus)
和_ (understrike)
替换。应该包装任何不兼容的库,使它们符合RFC 3548。
请注意,这需要您对(pad) =
字符进行网址编码,但我更喜欢使用标准base64字母表中的+
和/
字符进行URL编码。
答案 1 :(得分:8)
我认为没有对错。但最流行的编码是
'+/=' => '-_.'
谷歌,雅虎(他们称之为Y64)广泛使用它。我在Java上使用的最安全的编码器版本,Ruby支持这个字符集。
答案 2 :(得分:2)
我建议通过urlencode运行base64_encode的输出。例如:
function base64_encode_url( $str )
{
return urlencode( base64_encode( $str ) );
}
答案 3 :(得分:1)
如果你问的是正确的方法,我会使用正确的URL编码,而不是任意替换字符。第一个base64对您的数据进行编码,然后使用正确的URL编码(即%<code>
)进一步编码“=”等特殊字符。
答案 4 :(得分:0)
为什么不尝试将其包裹在urlencode()
中?文档here.