I am trying to figure out what is difference between these two ways of Base64 conversions:
First:
String base64EncodedMsg = Base64.getUrlEncoder().encodeToString(messageInBytes);
and
Second:
String base64EncodedMsg = new String(Base64.getEncoder().encode(messageInBytes));
Where messageInBytes
is of type byte[]
For a certain value of messageInBytes
, values of base64EncodedMsg
slightly differ.
With first call I get it as:
1HuW7rb7_l7NC7LwR7cRV2K-rlr7SnGdoEuGntxDKX8=
And with second call I get it as:
1HuW7rb7/l7NC7LwR7cRV2K rlr7SnGdoEuGntxDKX8=
Can someone please explain? Thanks in anticipation.
CodePudding user response:
The standard base-64 alphabet contains the characters
and /
, which have special meaning in a URL. To deal with this, there's a "URL friendly" variant of base-64, which doesn't use these characters - it uses -
and _
instead. This saves things from getting scrambled if you use a base-64 string in a URL.
Your two snippets of code show conversion to "URL friendly base-64" and standard base-64 respectively.
CodePudding user response:
These two methods of Base64
instance are just returning Encoder
with different policy of RFC4648 base64 conversion standard.
Just compare:
public static Encoder getEncoder() {
return Encoder.RFC4648;
}
and:
public static Encoder getUrlEncoder() {
return Encoder.RFC4648_URLSAFE;
}
Read more here:
-
CodePudding user response:
There are two Base64 alphabets of "digits." Both Base64 use 26 capital letters 26 small letters 10 digits = 62 digits. The normal Base64 adds
/
. The URL safe Base64 uses the neutral-
and_
.As a Base64 digit represents 6 bits, 4 digits represent 3 bytes. As padding at the end with
=
s is done.base64EncodedMsg = new String(Base64.getEncoder().encode(messageInBytes));
gives the normal Base64, but contains a non-portable error. The
new String(bytes)
uses the platform encoding and hence is not portable. As long as the platform encoding is a superset of ASCII it works, but encodings like wide characters (UTF-16) or EBCDIC would corrupt the message.Correct is
new String(bytes, StandardCharsets.US_ASCII)
or simply:base64EncodedMsg = Base64.getEncoder().encodeToString(messageInBytes);