To start with, this is wrong:
String base64Encoded = new String(imgData, StandardCharsets.UTF_8);
The image bytes you have do not represent UTF-8 encoded text, so it makes no sense to create a String out of the bytes, pretending that this is UTF-8 encoded text.
If you are using Java 8, then use the Base64 class available in the standard library:
import java.util.Base64;
// ...
byte[] imgData = (byte[]) base64.get("images");
String base64Encoded = Base64.getEncoder().encodeToString(imgData);
If you are not using Java 8, you can use a third-party library, for example Apache Commons Codec, which includes classes for Base64 encoding and decoding.
In android, you can use Base64 (android.util.Base64) to encoded byte[] to String;
String encodedString = Base64.encodeToString(byteArray, Base64.DEFAULT);
and
Decoding part as like following;
byte[] byteArray = org.apache.commons.codec.binary.Base64.decodeBase64(encodedString);
Usually this technique used in android app to send binary file/data to Server, using Web Service;
Java 8+
Encode or decode byte arrays:
byte[] encoded = Base64.getEncoder().encode("Hello".getBytes());
println(new String(encoded)); // Outputs "SGVsbG8="
byte[] decoded = Base64.getDecoder().decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64.getEncoder().encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(Base64.getDecoder().decode(encoded.getBytes()));
println(decoded) // Outputs "Hello"
For more info, see Base64.
Java < 8
Base64 is not bundled with Java versions less than 8. I recommend using Apache Commons Codec.
For direct byte arrays:
Base64 codec = new Base64();
byte[] encoded = codec.encode("Hello".getBytes());
println(new String(encoded)); // Outputs "SGVsbG8="
byte[] decoded = codec.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
Base64 codec = new Base64();
String encoded = codec.encodeBase64String("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(codec.decodeBase64(encoded));
println(decoded) // Outputs "Hello"
Android (with Java < 8)
If you are using the Android SDK before Java 8 then your best option is to use the bundled android.util.Base64.
For direct byte arrays:
byte[] encoded = Base64.encode("Hello".getBytes());
println(new String(encoded)) // Outputs "SGVsbG8="
byte [] decoded = Base64.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64.encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(Base64.decode(encoded));
println(decoded) // Outputs "Hello"
Other: Spring < 6.0.5
If for some reason Java's Base64 isn't suitable and you use Spring, see Base64Utils. This package, however, is deprecated as of 6.0.5 and so I don't recommend.
Use:
byte[] data = Base64.encode(base64str);
Encoding converts to Base64
You would need to reference commons codec from your project in order for that code to work.
For java8:
import java.util.Base64
JavaScript, 177 187 198 characters
function(d){c="";for(a=e=b=0;a<4*d.length/3;f=b>>2*(++a&3)&63,c+=String.fromCharCode(f+71-(f<26?6:f<52?0:f<62?75:f^63?90:87)))a&3^3&&(b=b<<8^d[e++]);for(;a++&3;)c+="=";return c}
For adding linebreaks, \r\n, after each 76th character, add 23 characters to the code:
function(d){c="";for(a=e=b=0;a<4*d.length/3;f=b>>2*(++a&3)&63,c+=String.fromCharCode(f+71-(f<26?6:f<52?0:f<62?75:f^63?90:87))+(75==(a-1)%76?"\r\n":""))a&3^3&&(b=b<<8^d[e++]);for(;a++&3;)c+="=";return c}
Demo code:
var encode = function(d,a,e,b,c,f){c="";for(a=e=b=0;a<4*d.length/3;f=b>>2*(++a&3)&63,c+=String.fromCharCode(f+71-(f<26?6:f<52?0:f<62?75:f^63?90:87))+(75==(a-1)%76?"\r\n":""))a&3^3&&(b=b<<8^d[e++]);for(;a++&3;)c+="=";return c};
//OP test case
console.log(encode([99, 97, 102, 195, 169])); // outputs "Y2Fmw6k=".
//Quote from Hobbes' Leviathan:
console.log(
encode(
("Man is distinguished, not only by his reason, but by this singular passion from " +
"other animals, which is a lust of the mind, that by a perseverance of delight " +
"in the continued and indefatigable generation of knowledge, exceeds the short " +
"vehemence of any carnal pleasure.")
.split('').map(function(i){return i.charCodeAt(0)})
)
);
C, 276 bytes
Quite a bump of this thread but I came up with this question myself a few days ago, then found out about code golfing, then found out about this thread.
Takes the 0-255 int array as first console arg (just a string). Uses K&R C style function parameter declaration and RFC 2045 encoding (except with no 76-character limit).
#define u(_)unsigned _:6;
b(i,j){putchar(j?i>61?43+i%2*4:i+65+6*(i>25)-75*(i>51):61);}i=-3;main(o,c)char**c;{char*s=c[1];for(;(i+=3)<strlen(s);){union{struct{u(a)u(b)u(c)u(d)};char s[3];}a;a.s[2]=s[i];a.s[1]=s[i+1];*a.s=s[i+2];b(a.d);b(a.c);b(a.b,a.s[1]);b(a.a,a.s[1]**a.s);}}
More 'readable' version of the algorithm (it was originally more clear but I started obfusc-golfing it right away so it turned out like this):
#include <stdio.h>
#include <string.h>
void b64_char(int i) {
putchar(i>61?43+i%2*4:i+65+6*(i>25)-75*(i>51));
}
int i=-3;
int main(int argc, char* argv[]) {
char* str = argv[1];
for (;(i+=3)<strlen(str);) {
union {
struct {unsigned a:6; unsigned b:6; unsigned c:6; unsigned d:6;};
char s[3];
} a;
a.s[2]=str[i];
a.s[1]=str[i+1];
a.s[0]=str[i+2];
b64_char(a.d);
b64_char(a.c);
a.s[1]?b64_char(a.b):putchar(61);
a.s[0]&&a.s[1]?b64_char(a.a):putchar(61);
}
return 0;
}
Defining the Base64 symbol table like that saved me a bunch of bytes. Basically taking advantage of the consecutiveness of letters in ASCII.
Also, architecture dependent since it only works on little endian machines, and fails non-deterministically when the unpassed parameter for the function b(2) happens to be 0.
This would have been a lot shorter on a big endian machine.
Can anybody shorten this any further?