我注意到每当我对base64进行编码时,最后会附加一个"=" . 我可以删除这个字符然后通过添加它来可靠地解码它,或者这是危险的吗?换句话说,是附加了"=" always ,还是仅在某些情况下?
我希望我的编码字符串尽可能短,这就是为什么我想知道我是否总能删除“=”字符并在解码之前将其添加回来 .
= 是填充 .
=
Wikipedia说
分配一个额外的填充字符,可用于强制编码输出为4个字符的整数倍(或等效于未编码的二进制文本不是3个字节的倍数);这些填充字符必须在解码时丢弃,但仍允许计算未编码文本的有效长度,当其输入二进制长度不是3字节的倍数时(最后一个非填充字符通常编码为最后一个)它表示的6位块将在其最低有效位上进行零填充,在编码流的末尾最多可能出现两个填充字符 .
如果您控制另一端,则可以在传输时将其删除,然后在解码之前重新插入(通过检查字符串长度) .请注意,数据在传输中不是有效的Base64 .
我编写了Apache的commons-codec-1.4.jar Base64解码器的一部分,在那个逻辑中我们没有填充字符 . 文件结束和流结束就像Base64消息完成任意数量的'='字符一样好!
我们在commons-codec-1.4中引入的URL-Safe变体省略了填充字符以保持较小的内容!
http://commons.apache.org/codec/apidocs/src-html/org/apache/commons/codec/binary/Base64.html#line.478
我想一个更安全的答案是“取决于你的解码器实现”,但从逻辑上讲,编写一个不需要填充的解码器并不困难 .
在JavaScript中,您可以执行以下操作:
// if this is your Base64 encoded string var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; // make URL friendly: str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''); // reverse to original encoding if (str.length % 4 != 0){ str += ('===').slice(0, 4 - (str.length % 4)); } str = str.replace(/-/g, '+').replace(/_/g, '/');
另见这个小提琴:http://jsfiddle.net/7bjaT/66/
添加了 = 用于填充 . base64字符串的长度应为4的倍数,因此根据需要添加1或2 = .
阅读:不,你不应该删除它 .
在Android上我使用这个:
全球
String CHARSET_NAME ="UTF-8";
Encode
String base64 = new String( Base64.encode(byteArray, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_CLOSE | Base64.NO_WRAP), CHARSET_NAME); return base64.trim();
Decode
byte[] bytes = Base64.decode(base64String, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_CLOSE | Base64.NO_WRAP);
在Java上等于这个:
private static String base64UrlEncode(byte[] input) { Base64 encoder = new Base64(true); byte[] encodedBytes = encoder.encode(input); return StringUtils.newStringUtf8(encodedBytes).trim(); }
private static byte[] base64UrlDecode(String input) { byte[] originalValue = StringUtils.getBytesUtf8(input); Base64 decoder = new Base64(true); return decoder.decode(originalValue); }
我从来没有跟踪“=”的问题,我也在使用Bouncycastle
如果您正在使用PHP,则以下函数将使用适当的填充将已剥离的字符串恢复为其原始格式:
<?php $str = 'base64 encoded string without equal signs stripped'; $str = str_pad($str, strlen($str) + (4 - ((strlen($str) % 4) ?: 4)), '='); echo $str, "\n";
6 回答
=
是填充 .Wikipedia说
如果您控制另一端,则可以在传输时将其删除,然后在解码之前重新插入(通过检查字符串长度) .
请注意,数据在传输中不是有效的Base64 .
我编写了Apache的commons-codec-1.4.jar Base64解码器的一部分,在那个逻辑中我们没有填充字符 . 文件结束和流结束就像Base64消息完成任意数量的'='字符一样好!
我们在commons-codec-1.4中引入的URL-Safe变体省略了填充字符以保持较小的内容!
http://commons.apache.org/codec/apidocs/src-html/org/apache/commons/codec/binary/Base64.html#line.478
我想一个更安全的答案是“取决于你的解码器实现”,但从逻辑上讲,编写一个不需要填充的解码器并不困难 .
在JavaScript中,您可以执行以下操作:
另见这个小提琴:http://jsfiddle.net/7bjaT/66/
添加了
=
用于填充 . base64字符串的长度应为4的倍数,因此根据需要添加1或2=
.阅读:不,你不应该删除它 .
在Android上我使用这个:
全球
Encode
Decode
在Java上等于这个:
Encode
Decode
我从来没有跟踪“=”的问题,我也在使用Bouncycastle
如果您正在使用PHP,则以下函数将使用适当的填充将已剥离的字符串恢复为其原始格式: