Question

I have a string encoded in Base64:

eJx9xEERACAIBMBKJyKDcTzR_hEsgOxjAcBQFVVNvi3qEsrRnWXwbhHOmzWnctPHPVkPu-4vBQ==

How can I decode it in Scala language?

I tried to use:

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

But when I compare the byte array with the correct one that I generated in Python language, there is an error. Here is the command I used in python:

import base64
base64.urlsafe_b64decode(compressed_code_string)

The Byte Array in Scala is:

(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)

And the one generated in python is:

(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)

Note that there is a single difference in the end of the array

Was it helpful?

Solution 2

There is unfortunately not just one Base64 encoding. The - character doesn't have the same representation in all encodings. For example, in the MIME encoding, it's not used at all. In the encoding for URLs, it is a value of 62--and this is the one that Python is using. The default sun.misc decoder wants + for 62. If you change the - to +, you get the correct answer (i.e. the Python answer).

In Scala, you can convert the string s to MIME format like so:

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

and then the Java MIME decoder will work.

OTHER TIPS

In Scala, Encoding a String to Base64 and decoding back to the original String using Java APIs:

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

Both Python and Java are correct in terms of the decoding. They are just using a different RFC for this purpose. Python library is using RFC 3548 and the used java library is using RFC 4648 and RFC 2045.

Changing the hyphen(-) into a plus(+) from your input string will make the both decoded byte data are similar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top