Кодировщик / декодер Base64 javax.xml.bind съедает последние два символа строки - PullRequest
3 голосов
/ 07 июня 2011

Мне нужно преобразовать некоторые строки, используя кодировку Base64, и был рад видеть, что мне не пришлось катить свой собственный конвертер - Java предоставляет один с javax.xml.bind.DataConverter.Однако у него есть некоторые проблемы.Вот вывод моего времени с Jython 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's a punctuated sentence.")
'Thisitsapunctuatedsenten'
>>> foo("\"foo\" \"bar\"")
'foob'
>>> foo("\"foo\" \"bar\"12")
'foobar12'
>>> foo("\"foo\" \"bar\"1")
'foob'

Как вы можете видеть, он вообще не обрабатывает не алфавитно-цифровые символы, а также часто - но не всегда - усекает строкуна два символа.

Я думаю, может быть, пришло время написать свой собственный класс, но теперь я обеспокоен тем, что либо: а) я не могу прочитать Javadoc или что-то б) класс неработать как положено.

Так что любая помощь очень ценится;заранее спасибо.

Ответы [ 6 ]

12 голосов
/ 07 июня 2011

hello не является строкой base64, поэтому синтаксический анализ не выполняется. Вы должны преобразовать строку в байтовый массив (попробуйте String(text).getBytes('UTF-8')), а затем вызвать DC.printBase64Binary() в байтовом массиве, чтобы получить данные в Base64.

DC.parseBase64Binary() затем преобразует эти данные в кодировке Base64 обратно в байтовый массив (который затем можно преобразовать обратно в строку).

6 голосов
/ 31 января 2012

Несколько результатов, потраченных на решение аналогичной проблемы на платформе GAE (декодер Base64 потребляет последние (два) символа при декодировании строки base64 из Facebook)

Если закодированная строка не имеет длины 4 * n, тогда метод DatatypeConverter.parseBase64Binary может отбрасывать некоторые завершающие символы (что делает полезную нагрузку JSON синтаксически неправильной). Моим решением было добавить следующий код:

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

Что касается примера кода в вопросе, я бы предложил изменить, где тестовая строка кодируется сначала , а затем декодируется, то есть:

return DC.parseBase64Binary(DC.printBase64Binary(String(text).getBytes()))
1 голос
/ 07 июня 2011

Вы не даете ему полный base64 (включая final padding ) и т. Д. Для начала.Если вы дадите ей полную строку base64, все будет в порядке.

Вам следует только пытаться интерпретировать данные, как если бы они были base64, если они действительно base64 для запускас.Делать это с произвольными последовательностями символов - плохая идея.

Непонятно, что вы на самом деле пытаетесь сделать, если вы на самом деле не начинаете с данных base64.Вы говорите о «преобразовании некоторых строк» ​​- они base64 или нет?

0 голосов
/ 06 ноября 2013

Я получаю данные в технике Deflater zip.Итак, небольшая функция для распаковки:

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;
}

Затем вы можете преобразовать байт в новую строку или что-нибудь еще.

0 голосов
/ 09 октября 2012
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 голосов
/ 07 июня 2011

Я думаю, что класс javax.xml.bind.DatatypeConverter может работать с данными XML или типами XSD, так как метод JavaDoc указывает для параметр :

Строка, содержащая лексическое представление xsd: base64Binary

Лично мне было бы неудобно использовать класс / библиотеку, ориентированную на преобразования XML для чего-то подобного.

Взгляните на библиотеку кодеков общего пользования , которая имеет простой в использовании Base64 класс .

...