如何在Scala或Java中解码Base64字符串?

11

我有一个Base64编码的字符串:

eJx9xEERACAIBMBKJyKDcTzR_hEsgOxjAcBQFVVNvi3qEsrRnWXwbhHOmzWnctPHPVkPu-4vBQ==

我该如何在Scala语言中解码它?

我尝试使用:

val bytes1 = new sun.misc.BASE64Decoder().decodeBuffer(compressed_code_string)

但是当我将这个字节数组与我在Python语言中生成的正确字节数组进行比较时,出现了一个错误。下面是我在Python中使用的命令:

import base64
base64.urlsafe_b64decode(compressed_code_string)

Scala中的字节数组为:

(120, -100, 125, -60, 65, 17, 0, 32, 8, 4, -64, 74, 39, 34, -125, 113, 60, -47, -2, 17, 44, -128, -20, 99, 1, -64, 80, 21, 85, 77, -66, 45, -22, 18, -54, -47, -99, 101, -16, 110, 17, -50, -101, 53, -89, 114, -45, -57, 61, 89, 15, -69, -2, 47, 5)

而Python生成的字节数组为:

(120, -100, 125, -60, 65, 17, 0, 32, 8, 4, -64, 74, 39, 34, -125, 113, 60, -47, -2, 17, 44, -128, -20, 99, 1, -64, 80, 21, 85, 77, -66, 45, -22, 18, -54, -47, -99, 101, -16, 110, 17, -50, -101, 53, -89, 114, -45, -57, 61, 89, 15, -69, -18, 47, 5)

请注意,数组末尾只有一个差异。

3个回答

16

在Scala中,使用Java APIs将字符串编码为Base64并解码回原始字符串:

import java.util.Base64
import java.nio.charset.StandardCharsets

scala> val bytes = "foo".getBytes(StandardCharsets.UTF_8)
bytes: Array[Byte] = Array(102, 111, 111)

scala> val encoded = Base64.getEncoder().encodeToString(bytes)
encoded: String = Zm9v

scala> val decoded = Base64.getDecoder().decode(encoded)
decoded: Array[Byte] = Array(102, 111, 111)

scala> val str = new String(decoded, StandardCharsets.UTF_8)
str: String = foo

6
很不幸,Base64编码并不只有一种。在所有的编码中,“-”字符没有相同的表示。例如,在MIME编码中,“-”根本没有使用。在URL编码中,“-”是62的值——这是Python正在使用的值。默认的sun.misc解码器想要“+”表示62。如果你把“-”改成“+”,你就会得到正确的答案(即Python的答案)。
在Scala中,你可以这样将字符串“s”转换为MIME格式:
s.map{ case '-' => '+'; case '_' => '/'; case c => c }

然后Java MIME解码器将起作用。


4

在解码方面,Python和Java都是正确的。它们只是使用不同的RFC来实现这个目的。Python库使用的是RFC 3548,而所使用的Java库使用的是RFC 4648RFC 2045

将输入字符串中的连字符(-)改为加号(+),可以使得两个解码后的字节数据相似。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接