Hussein Harake

How to make Base64 encoding and decoding safe?

Posted in PHP by harake on January 30, 2010

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:

  1. consumes more memory resources (HDD and / OR RAM)
  2. 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

Advertisement

3 Responses

Subscribe to comments with RSS.

  1. Jamel said, on February 5, 2010 at 10:26 pm

    It is working, but can you give me an example where It is better to safe_base64_encode the variables in URLs?

  2. harake said, on February 5, 2010 at 10:52 pm

    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

  3. Rosetta Stone Irish said, on December 2, 2010 at 10:02 am

    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.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.