2015-04-29 67 views
4

我使用URL安全的Base64编码来编码我的随机生成的字节数组。但我在解码时遇到问题。当我解码两个不同的字符串(除了最后的字符都相同),它会产生相同的字节数组。例如,对于既"dGVzdCBzdHJpbmr""dGVzdCBzdHJpbmq"字符串的结果是一样的:为什么Base64.decode为不同的字符串产生相同的字节数组?

Array(116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 106) 

对于编码/解码我以这种方式使用java.util.Base64

// encoding... 
Base64.getUrlEncoder().withoutPadding().encodeToString(myString.getBytes()) 
// decoding... 
Base64.getUrlDecoder().decode(base64String) 

这是什么碰撞的原因是什么?对于最后一个字符以外的字符也可以吗?我怎样才能解决这个问题,并解码为每个不同的字符串返回一个不同的字节数组?

+1

你确定'withoutPadding()'选项是个好主意吗? – haraldK

+1

基本上,它*无关紧要,如果相同的数组可以用两种不同的方式编码。重要的是,如果您接受一个数组,对其进行编码,然后对其进行解码,那么您将获得相同的数组。 –

+1

这并不是说真的很有趣,你有两个字符串都是相同的。 :-)很确定这只是最后有未使用位的问题(因为Base64跨越字节边界对八位字节进行编码),但我必须确定这些位。 –

回答

7

您所看到的问题是由于您在“结果”(11个字节)中拥有的字节数并未完全“填充”Base64编码字符串的最后一个字符而造成的。

请记住,Base64将每个8位实体编码为6位字符。结果字符串需要正好11 * 8/6字节或14 2/3字符。但是你不能写部分字符。只有前4位(或最后一个字符的2/3)很重要。最后两位不解码。因此,所有的:

dGVzdCBzdHJpbmo 
dGVzdCBzdHJpbmp 
dGVzdCBzdHJpbmq 
dGVzdCBzdHJpbmr 

全部解码到相同的11个字节(116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 106)。 PS:如果没有填充,某些解码器会尝试解码“最后一个”字节,并且会得到一个12字节的结果(最后一个字节不同)。这是我评论的原因(询问withoutPadding()选项是否是一个好主意)。但是你的解码器似乎处理这个问题。

0

可能这是Base64编码和解码的方式......看看这个this是否有帮助。 请阅读以下说明以了​​解Base 64的实际工作情况。如果数组字符串在末尾有差异,则编码值将为,可能被反映在同一位置。

相关问题