How to make Base64 encoding and decoding safe?
base64 and the PHP manual
string base64_encode ( string data )
base64_encode() returns data encoded with base64.
This encoding is designed to make binary data survive transport through transport layers that are not 8-bit clean, such as mail bodies.
Base64-encoded data takes about 33% more space than the original data.
Example 1. base64_encode() example
<?php $str = 'This is an encoded string'; echo base64_encode($str); ?>
This example will produce:
VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==
Do we really need the base64?
As far as I know, data at any rate should not be converted in database because conversion:
- consumes more memory resources (HDD and / OR RAM)
- consumes more processing resources (CPU and usually this affects performance)…
In fact, sometimes we need the base64 not for storage but for data transportation
example, some non-alpha-numeric characters can not be transported easily via URL.
Cconverting by encoding any string to base-64 leads to another string where each character is one of this set
{
- A to Z (26 characters)
- a to z (26 characters)
- 0 to 9 (10 characters)
- + (the plus operator character)
- / (the famous URL slash character)
}
so there are 64 possible characters.
But there is also the = (the equal operator character) which is used for padding when the original string is not a multiple of three characters.
we are not here to discuss the concept whether it is right or not, but as everyone of us knows, the three characters
- “+”
- “/”
- “=”
have special meanings in URL, so it is better to convert them to some safe non-alpha-numeric characters
One of the successfull solution I have tested is converting the
- + to – (the dash or the minus operator character)
- / to _ (the underscore)
- = to * (the star or the multiply by operator character)
The code
So In each application that needs to safely transfer some variables via URL, two functions are required
function safe_base64_encode($value) { if (!is_string($value)) { return false; } return str_replace(array('+', '/', '='), array('-', '_', '*'), base64_encode($value)); }
which returns the safe encoded base-64 string or false when the argument was not string
and
function isBase64($value, $safe = false) {
if (!is_string($value)) {
return false;
}
if (!$safe) {
$regexp = '/^([A-Za-z0-9\+\/]{4})*([A-Za-z0-9\+\/]{2}(=|[A-Za-z0-9\+\/])=)?$/';
} else {
$regexp = '/^([A-Za-z0-9\-_]{4})*([A-Za-z0-9\-_]{2}(\*|[A-Za-z0-9\-_])\*)?$/';
}
if (preg_match($regexp, $value) != 1) {
return false;
}
if ($safe) {
$value = str_replace(array('-', '_' ,'*'), array('+', '/' ,'='), $value);
}
return base64_decode($value);
}
which is used to check if the first argument is base64-encoded where the second argument is to force the safe option, it returns false on error or the original string (base64-decoded)
Please leave a comment, If you like this article or have one or more remark(s) on it
It is working, but can you give me an example where It is better to safe_base64_encode the variables in URLs?
You have a search engine in your web site
the URL of the search results is always something like this
http://www.yourwebsite.com/search/the_keyword_you_are_searching
what if the keyword you are searching is something like this ’4/2=2′
if you put it classically, the search URL will be
http://www.yourwebsite.com/search/4/2=2
which in the best case will not give the expected answers.
that is why we safe_base64_encode this kind of keywords to avoid having errors
After reading this I thought it was quite informative. I appreciate you taking the time to put this blog piece together. I once once more discover myself spending method to significantly time both reading and commenting. What ever, it was still worth it.