Base64 encoder / decoder Javax.xml.bind eats the last two characters of a string

I needed to convert some strings using Base64 encoding, and I was glad to see that I did not need to run my own converter. Java provides one javax.xml.bind.DataConverter . However, he has some problems. Here is the output of my time using JPL REPL:

 >>> import javax.xml.bind.DatatypeConverter as DC >>> import java.lang.String as String >>> def foo(text): ... return DC.printBase64Binary(DC.parseBase64Binary(String(text))) ... >>> foo("hello") 'hell' >>> foo("This, it a punctuated sentence.") 'Thisitsapunctuatedsenten' >>> foo("\"foo\" \"bar\"") 'foob' >>> foo("\"foo\" \"bar\"12") 'foobar12' >>> foo("\"foo\" \"bar\"1") 'foob' 

As you can see, it does not process non-alphanumeric characters at all, and also often - but not always - trims a string with two characters.

I think the time has come to just write my own class, but now I'm worried that either: a) I can not read javadoc or something b) the class does not work as expected.

So any help is much appreciated; thanks in advance.

+3
java encoding base64 decoding
source share
6 answers

hello not a base64 string, so parsing is not performed. You must convert the string to an array of bytes (try String(text).getBytes('UTF-8') ), and then call DC.printBase64Binary() in the byte array to get the data in Base64.

DC.parseBase64Binary() then converts the Base64 encoded data back to a byte array (which can then be converted back to a string).

+12
source share

A few results after spending time solving a similar problem on the GAE platform (Base64 decoder eats the last (two) characters when decoding a base64 string from facebook)

If the encoded string does not have a length of 4 * n, then the DatatypeConverter.parseBase64Binary method may discard some trailing characters (rendering of syntaxically incorrect JSON loading). My solution was to add the following code:

 while (payload.length() % 4 != 0) payload += "="; 

As for the sample code in the question, I would suggest a change in which the test string gets first and then decodes, i.e.:

 return DC.parseBase64Binary(DC.printBase64Binary(String(text).getBytes())) 
+5
source share

You will not give it full base64 (including the final addition ) and so on. If you give it the full base64 string, everything should be fine.

You should only try to interpret the data as if it is base64, if in fact it is base64 for starters. Doing this with arbitrary character sequences is a bad idea.

It is not clear what you are really trying to do if you really are not starting with base64 data. Are you talking about "converting some strings" - are they base64 or not?

+1
source share

I think the javax.xml.bind.DatatypeConverter class can expect to work with XML data or XSD types, since the JavaDoc method specifies a parameter :

A string containing the lexical representation of xsd: base64Binary

Personally, I would not feel comfortable using an XML transform-oriented class / library for something like this.

Take a look at the commons-codec library , which has an easy-to-use Base64 class .

0
source share
 import javax.xml.bind.DatatypeConverter; import java.io.UnsupportedEncodingException; import java.lang.String ; public class HttpBasicAuthenticationHeader { public static void main(String[] args) { DatatypeConverter dc; String str="ENCODE"; String s=""; try { s=javax.xml.bind.DatatypeConverter.printBase64Binary(str.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(s); } 
0
source share

I get data using the Deflater zip technique. So, a little function to unpack:

 public byte[] descomprimir() throws IOException, DataFormatException { final String wsData = "eNqzsa/IzVEoSy0qzszPs1Uy1DNQUkjNS85PycxLt1XyDPbXtbAwtdQ1VLK347JJTixJzMlPzy/Wt+MCAAU6ETY="; byte[] data = DatatypeConverter.parseBase64Binary(wsData); Inflater inflater = new Inflater(); inflater.setInput(data); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); byte[] buffer = new byte[1024]; while (!inflater.finished()) { int count = inflater.inflate(buffer); outputStream.write(buffer, 0, count); } outputStream.close(); byte[] output = outputStream.toByteArray(); return output; } 

Then you can convert the byte to a new line or something else.

0
source share

All Articles