I am encoding the URL suffix of my application:
$url = 'subjects?_d=1';
echo base64_encode($url);
// Outputs
c3ViamVjdHM/X2Q9MQ==
Notice the slash before 'X2'.
Why is this happening? I thought base64 only outputted A-Z, 0-9 and '=' as padding? I have tried using an online base64 encoder to check, and it seems base64 always does this. I can't tell if it's the underscore "_" or the question mark "?" or the "=" perhaps?
No. The Base64 alphabet includes A-Z, a-z, 0-9 and +
and /
.
You can replace them if you don't care about portability towards other applications.
See: http://en.wikipedia.org/wiki/Base64#Variants_summary_table
You can use something like these to use your own symbols instead (replace -
and _
by anything you want, as long as it is not in the base64 base alphabet, of course!).
The following example converts the normal base64 to base64url as specified in RFC 4648:
function base64url_encode($s) {
return str_replace(array('+', '/'), array('-', '_'), base64_encode($s));
}
function base64url_decode($s) {
return base64_decode(str_replace(array('-', '_'), array('+', '/'), $s));
}
Sorry, you thought wrong. A-Za-z0-9 only gets you 62 characters. Base64 uses two additional characters, in PHP's case /
and +
.
In addition to all of the answers above, pointing out that / is part of the expected base64 alphabet, it should be noted that the particular reason you saw a / in your encoded string, is because when base64 encoding ASCII text, the only way to generate a / is to have a question mark in a position divisible by three.
There is nothing special in that.
The base 64 "alphabet" or "digits" are A-Z,a-z,0-9 plus two extra characters + (plus) and / (slash).
You can later encode / with %2f if you want.
A-Z is 26 characters.
0-9 is 10 characters.
= is one character. That gives a total of 37 characters, which is some way short of 64.
/
is one of the 64 characters. You can see a complete list on the wikipedia page.
Not directly related, and enough people above have answered and explained solutions quite well.
However, going a bit outside of the scope of things. If you want readable base text, try looking into Base58. It's worth considering if you want only alphanumeric characters.
For base64 the valid charset is:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
the = is used as filler for the last bytes
M.