Eric Nelson
Eric Nelson

Reputation: 346

Java 8 Base64 Encode (Basic) doesn't add new line anymore. How can I reimplement this?

I essentially have the exact opposite problem as

new-line-appending-on-my-encrypted-string

It seems like the old Java Base64 utility would always add new lines every 76 characters when returning a string, but using the following code, I don't get those breaks I need.

    Path path = Paths.get(file);
    byte[] data = Files.readAllBytes(path);
    String txt= Base64.getEncoder().encodeToString(data);

Is there an easy way to tell the encoder to add the newlines?

I've tried implementing a stringbuilder to insert the newlines, But it ends up changing the entire output (I copy the text from java console to HxD editor, and compare against my known working 'BLOB' with newlines).

    String txt= Base64.getEncoder().encodeToString(data);

    //Byte code for newline
    byte b1 = 0x0D;
    byte b2 = 0x0A;     

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < txt.length(); i++) {
        if (i > 0 && (i % 76 == 0)) {
            sb.append((char)b1);
            sb.append((char)b2);

        }

        sb.append(txt.charAt(i));
    }

EDIT (in response to question):

It's not the easiest thing to explain, but when I don't use string builder, the output of the encode will start like this:

AAAAPAog4lBVgGJrT2b+mQVicHN3d////////3hhcDJiLWVtMjUwLWVtMjUwLWRldjA0NTUAAAAAAA

But I want it to look like this:

AAAAPAog4lBVgGJrT2b+mQVicHN3d////////3hhcDJiLWVtMjUwLWVtMjUwLWRldjA0NTUAAAAA..AA

As you can see, the ".." represents 0x0D and 0X0A or a newline, which is insterted at the 76th character (this is what the old base64 would output).

However, when I append the bytes b1 and b2 (newline) after the 76th character, the output becomes:

BPwAFHwA0CUFoG8AgDRCAAIlQgAAJUIAAhUfNEIAAiUkmw/0fADQFSInART/ADUlfADQFQE0fADQ..

So it looks like the ".." is in the right spot, but everything before it is different.

Thanks!

Upvotes: 0

Views: 5879

Answers (2)

user2104560
user2104560

Reputation:

Today I splitted Base64 representation of X509Certificate with the following code:

StringBuilder sb = new StringBuilder();
int chunksCount = str.length()/76;
for(int i=0;i<chunksCount;i++){
    sb.append(str.substring(76*i,76*(i+1))).append("\r\n");
}
if(str.length() % 76 != 0) sb.append(str.substring(76*chunksCount)).append("\r\n");

I think, adding big parts better than iterating over each letter. Also, some libraries provide Base64 encoder with special parameter allowing to split with required part size but I had to use some library without such feature.

Upvotes: 0

nneonneo
nneonneo

Reputation: 179552

You want getMimeEncoder instead:

MIME

Uses the "The Base64 Alphabet" as specified in Table 1 of RFC 2045 for encoding and decoding operation. The encoded output must be represented in lines of no more than 76 characters each and uses a carriage return '\r' followed immediately by a linefeed '\n' as the line separator. No line separator is added to the end of the encoded output. All line separators or other characters not found in the base64 alphabet table are ignored in decoding operation.

(emphasis mine)

Note that the encoding scheme is otherwise the same as the basic encoder from getEncoder - they are both derived from RFC 2045.

Upvotes: 6

Related Questions