0
votes

I need to transfer data between Java and C application.

Binary data encoded using org.apache.commons.codec.binary.Base64Base64.encodeBase64(binaryData) is not getting properly decoded in "C" application.

I think I need to encode using the "ASCII" pattern.

So how to do Base64 ASCII encoding of binary data in Java ?

3

3 Answers

2
votes

Base64 is ASCII encoding. When you encode binary data with a Base64 algorithm, the output is ASCII bytes. That is the main purpose of Base64. Here is some code to prove it:

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import org.apache.commons.codec.binary.Base64;

public class Main {
    public static void main(String[] args) {
        String s = "我愛我的狗.";
        byte[] base64Encoded = Base64.encodeBase64(s.getBytes());
        Charset ascii = Charset.forName("US-ASCII");
        String asciiEncoded = new String(base64Encoded, ascii);

        System.out.println(DatatypeConverter.printHexBinary(base64Encoded));
        System.out.println(DatatypeConverter.printHexBinary(asciiEncoded.getBytes()));
    }
}

The Apache Base64 encoder you are using is reliable. What is the C decoder your are using? How are you transferring the data from Java to C? Are you sure you are "receiving" the same bytes on the C side?

One possible problem is that you are using different versions of the Base64 encoding algorithm to encode/decode your bytes. There are many variants of Base64. See this article, for example.

Is it possible you have "safe URL encoding" enabled/disabled in one or the other encoder/decoder?

0
votes

If using JDK 8 is an option for you, check out java.util.Base64 and the nested class, java.util.Base64.Encoder.

Base64.getEncoder() will return you a Base64.Encoder.

0
votes

There are several different variants of "base64"; you may have come across two incompatible ones.

https://en.wikipedia.org/wiki/Base64#Variants_summary_table

The main differences are the "last two" characters of the encoding set, and line length limitations.

java.util.Base64 lets you select between three different variants https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html

When there is a choice, I recommend everybody to go with the official RFC 4648 section 4 encoding. https://www.rfc-editor.org/rfc/rfc4648#section-4