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

如何在Scala或Java中解码Base64字符串?,java,python,scala,base64,decoding,Java,Python,Scala,Base64,Decoding,我有一个用Base64编码的字符串: eJx9xEERACAIBMBKJyKDcTzR_hEsgOxjAcBQFVVNvi3qEsrRnWXwbhHOmzWnctPHPVkPu-4vBQ== 我如何用Scala语言解码它 我尝试使用: val bytes1 = new sun.misc.BASE64Decoder().decodeBuffer(compressed_code_string) 但是,当我将字节数组与用Python语言生成的正确数组进行比较时,出现了一个错误。以下是我在pytho

我有一个用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、-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)

请注意,在数组的末尾有一个单独的差异,不幸的是。
-
字符在所有编码中的表示形式并不相同。例如,在MIME编码中,根本不使用它。在URL的编码中,它的值是62——这是Python正在使用的值。默认的sun.misc解码器需要62的
+
。如果将
-
更改为
+
,则会得到正确的答案(即Python答案)

在Scala中,您可以将字符串
s
转换为MIME格式,如下所示:

s.map{ case '-' => '+'; case '_' => '/'; case c => c }

然后Java MIME解码器就会工作。

Python和Java在解码方面都是正确的。他们只是为了这个目的使用了不同的RFC。Python库使用的是
RFC3548
,使用的java库使用的是
RFC4648
RFC2045


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

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

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(bytes, StandardCharsets.UTF_8)
str: String = foo