What works for me is to change the b64encode line to:
myObj = [base64.b64encode(data).decode('ascii')]
This is explained in https://stackoverflow.com/a/42776711 :
base64 has been intentionally classified as a binary transform.... It was a design decision in Python 3 to force the separation of bytes and text and prohibit implicit transformations.
The accepted answer doesn't work for me (Python 3.9) and gives the error:
Traceback (most recent call last):
File "/tmp/x.py", line 4, in <module>
myObj = [base64.b64encode(data)]
File "/usr/lib64/python3.9/base64.py", line 58, in b64encode
encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
Answer from jmou on Stack OverflowWhat works for me is to change the b64encode line to:
myObj = [base64.b64encode(data).decode('ascii')]
This is explained in https://stackoverflow.com/a/42776711 :
base64 has been intentionally classified as a binary transform.... It was a design decision in Python 3 to force the separation of bytes and text and prohibit implicit transformations.
The accepted answer doesn't work for me (Python 3.9) and gives the error:
Traceback (most recent call last):
File "/tmp/x.py", line 4, in <module>
myObj = [base64.b64encode(data)]
File "/usr/lib64/python3.9/base64.py", line 58, in b64encode
encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
Try
data = b'foo'.decode('UTF-8')
instead of
data = b'foo'
to convert it into a string.
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
Byte[] -> String: use system.convert.tobase64string
Convert.ToBase64String(byte[] data)
String -> Byte[]: use system.convert.frombase64string
Convert.FromBase64String(string data)
Base64 is a way to represent bytes in a textual form (as a string). So there is no such thing as a Base64 encoded byte[]. You'd have a base64 encoded string, which you could decode back to a byte[].
However, if you want to end up with a byte array, you could take the base64 encoded string and convert it to a byte array, like:
string base64String = Convert.ToBase64String(bytes);
byte[] stringBytes = Encoding.ASCII.GetBytes(base64String);
This, however, makes no sense because the best way to represent a byte[] as a byte[], is the byte[] itself :)
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?
However, I do not know what length I need to have the signature at so when I encode it, it can be that exact size.
Well, base64 uses 4 characters (from an alphabet of size 64) to encode 3 bytes (3 bytes contain 24 bits; 24/4 = 6 bits per base64 character).
Hence, if the signature was 72 bytes long, that would translate to (72/3)*4 = 96 characters you require.
Now, base64 typically has a === trailer to signify the end of the encoding; are you counting that?
base64 is defined on rfc4648
As poncho mentions, it has an overhead of 33%, and thus 96 / 4 ร 3 = 72 bytes needed