【问题标题】:Why do Base64.decode produce same byte array for different strings?为什么 Base64.decode 为不同的字符串生成相同的字节数组?
【发布时间】:2015-04-29 10:38:51
【问题描述】:

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

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)

这次碰撞的原因是什么?是否也可以使用除最后一个以外的字符?我该如何解决这个问题并让解码为每个不同的字符串返回一个不同的字节数组?

【问题讨论】:

  • 您确定withoutPadding() 选项是个好主意吗?
  • 从根本上说,如果同一个数组可以用两种不同的方式编码,那没关系。重要的是,如果您获取一个数组,对其进行编码,然后对其进行解码,您会得到相同的数组。
  • 这并不是说你有两个相同的字符串并不有趣。 :-) 很确定这只是最后有未使用的位的问题(因为 Base64 跨越字节边界对八位字节进行编码),但我必须确定这些位。
  • @haraldK 我用它来删除末尾的尾随“=”字符。实际上,我尝试了填充,结果是一样的。

标签: java encoding base64 decoding


【解决方案1】:

您看到的问题是由于“结果”中的字节数(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() 选项是否是个好主意)。但是您的解码器似乎可以处理这个问题。

【讨论】:

    【解决方案2】:

    可能这就是 Base64 编码和解码的方式...看看这 this 是否有帮助。 阅读下面的描述了解Base 64的实际工作。如果数组字符串末尾有差异,编码值将可能反映在同一个地方。

    【讨论】:

      【解决方案3】:

      您显示的数组是“test strinj”的 ASCII 表示(参见http://www.unit-conversion.info/texttools/ascii/),似乎不是任何东西的 base64 表示。

      您似乎正在分析错误的“结果”数组

      【讨论】:

        猜你喜欢
        • 2011-03-20
        • 1970-01-01
        • 2016-09-25
        • 2021-03-22
        • 2020-07-24
        • 2021-09-28
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        相关资源
        最近更新 更多