2014-01-23 158 views
3

我有一个字符串编码为Base64:如何解码Scala或Java中的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)

注数组末尾有一个单独的差异

回答

5

不幸的是not just one Base64 encoding-字符在所有编码中不具有相同的表示形式。例如,在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

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

1

在Scala中,编码串为Base64和解码回原来的字符串:

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

scala> val bytes = "foo".getBytes("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