Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Wednesday, September 12, 2018

Removing Symbols from a UTF-8 String and Retaining the Characters in PHP

You will often have strings that contain symbols, where you only want to extract just the text component of this string.

Using a regular expression (regex) in PHP, you can do this quite easily...

$string = "12345-hello, 汉语!!!";
$string = preg_replace('/[^(\p{L}\p{N}\s)]/u', '', $string);
print($string); // output is: 12345hello 汉语

Each part of the preg_replace here can be explained without much effort.

/regex/u - The two slashes indicate what is matched against. The U indicates UTF-8.

[class] - Within this, the two brackets indicate the one single class of values considered valid.

^(values) - We are looking for things that do not match values.

\p{L} - This value is all UTF-8 characters.

\p{N} - This value is all numbers.

\s - This value is all white spacing.

So, anything that doesn't match a letter, a number, or a space (i.e., /[^(\p{L}\p{N}\s)]/), is replaced with '', or the empty string.

Tuesday, September 11, 2018

Converting Accented Characters to Non-Accented Equivalents in PHP

For some reason or other, you may want to have a string of accented characters converted to its equivalent, such as "hëllo" to "hello".

Doing this in PHP is easy. You will have some input like this...

$input = "hëllo";

Then you can convert and see the output like this...

$output = iconv('UTF-8', 'ASCII//TRANSLIT', $input);
print($output);

Output here is "hello", and our problem is solved very easily!

Of course, for the most part, you should not need to do this. Accepting the entirety of UTF-8's range in diversity and color is usually a good thing for any code solution.

Monday, September 10, 2018

How do I convert to/from 24-hour time and AM/PM time in PHP?

In databases, times and datetimes may be stored as "13:30:00" or "1984-05-01 15:45:59".

But you may want to convert this to something that displays with AM/PM, or maybe you want to collect a time that is AM/PM and store it according to your DB schema.

You can display 24-hour time in AM/PM with...

print date('G:ia', strtotime("13:30:00"));

And a 24-hour datetime with in AM/PM with...

print date('Y-m-d G:ia', strtotime("1984-05-11 13:30:00"));

If you wanted to go in the opposite direction, and display an AM/PM time with 24-hour time...

print date('H:i:s', strtotime("1:30 AM"));

And if you want to display AM/PM datetime in 24-hour datetime format...

print date('Y-m-d H:i:s', strtotime("1:30 AM"));

Tuesday, September 4, 2018

What is a stacktrace? How do I use a stacktrace to debug my code?

A stacktrace is a list of all the functions and all the files called at a particular point in a piece of code. It may be generated by a programming exception (a runtime error), a break-point, or simply by developer-triggered logging.

If your code crashes, this is useful because it will tell you everywhere that code executed in order to produce the error. Generally, these are good places to start looking for finding a solution to the bug.

Take a look at this PHP error stacktrace...

Stack trace:
#0 /home/anarchocommie/classes/Format/HTML.php(181): users->viewuser()
#1 /home/anarchocommie/classes/Networking/Handler.php(536): HTML->Display()
#2 /home/anarchocommie/classes/Networking/Handler.php(520): Handler->HandleRequest_Content_Format()
#3 /home/anarchocommie/classes/Networking/Handler.php(458): Handler->HandleRequest_Content()
#4 /home/anarchocommie/revoltlib.com/index.php(9): Handler->HandleRequest()
#5 {main}

In this particular stacktrace, index.php was first called (at line 9 in index.php), which then called Handler->HandleRequest(), then Handler->HandleRequest() called Handler->HandleRequest_Content(), and then Handler->HandleRequest_Content() called Handler->HandleRequest_Content_Format(), and then Handler->HandleRequest_Content_Format() called HTML->Display() -- and so on.

Using a stack trace like this, you can find out how and why your errors occurred.

Saturday, September 1, 2018

Difference between Single-Quoted and Double-Quoted Strings in PHP

There are two types of quoted strings in PHP: single-quoted and double-quoted.

With a single quoted string, characters using by PHP to define a string must be escaped, like so...

$stringa = 'hello, \'friend\', how are you?'; // string: hello, 'friend', how are you?
$stringb = "\\file\\directory\\location.php"; // string: \file\directory\location.php

But you may also have a double-quoted string, which means that the content is more dynamic, like so...

$stringc = "hello, $friend"; // string: hello joe, ann, tom, etc..
$stringd = "where are all the ${type}s?" // string: where are all the friends? books? beers?

Single-quoted strings always execute much faster than double-quoted strings. But there are things in double-quoted strings that cannot be done by single-quoted strings alone. They will need concatenation, like so...

$stringe = "hello, " . $friend; // string: hello joe, ann, tom, etc..
$stringf = "where are all the " . $type . "s?"; // string: where are all the friends? books? beers?

If you are using single-quoted strings, you only get this performance boost by using apostrophes ("static strings", AKA: Single Quoted Strings), and not by using the quotes ("interpolated strings", AKA: Double-Quoted Strings).

Friday, August 31, 2018

Changing the Filename of a File Downloaded over a PHP Script

You may be downloading files on your server with PHP by a combination of the header() and readfile() functions, like so...

header("Content-disposition: attachment;filename=MyFileName.txt");
readfile("../data/MyFileName.txt");

The filename on the server, and the one the user sees, will both have the same name. But you can change the filename the user sees, with something like this...

header("Content-disposition: attachment;filename=MyUSERONLYFileName.txt");
readfile("../data/MyFileName.txt");

Your server knows to look for the file in ../data/MyFileName.txt, and now, your user will receive a file with teh name of MyUSERONLYFilename.txt, instead of MyFileName.txt.

Thursday, August 30, 2018

How do I Download a File to the User with my PHP script?

If you have a text file on your PHP server, you may have tried to download it through your PHP script with just this...

readfile("../data/MyTextFileName.txt");

But, as you would have noticed, it doesn't download the file. It displays the file contents in the browser.

To download the file, you must also include headers, used by HTTP to determine how to treat the web server's response, like this...

header("Content-disposition: attachment;filename=MyFileName.txt");
readfile("../data/MyTextFileName.txt");

After running the above, the user will be prompted with a question about whether they want to open or save a downloaded file, or however their particular browser is configured to handle downloads.

Wednesday, August 29, 2018

Creating a GZip Archive on Your PHP Server to Serve to Web Users

Gzip is a popular zip-archive format for storing files in the long-term. Users benefit from this by reducing the download time, or by being able to group files together in a single download link.

You may have files on your PHP server, of any type (image, documents, code, etc.), and you may want to zip these files in a GZip archive automatically with your PHP script.

You can create a gzip file with something like this...

$filep = gzopen("../data/MyZipFileName.gz", 'w9');

Then you write whatever text you want to it with something like this...

gzwrite($filep, $text);

When you are finished, you let the PHP server know you're done by adding this to the end of your script...

gzclose($filep);

If you want to download this as a file, you need to send file headers, so that you download the gzip file at the PHP URL, instead of just looking at the gzip file contents through the browser (which would be a garbled mess, as it is a compressed archive).

You can do that with this...

header("Content-disposition: attachment;filename=MyArchiveFile.gz");
readfile("../data/MyZipFileName.gz");

Tuesday, August 28, 2018

Downloading and Unzipping GZip on Your PHP Server From Another Web Server

Some site may offer a gzip file that you want to run with your PHP script, but that gzip file is always being updated and you want your script to download the newest version and use its contents.

This can be done very easily.

First, download the file you want to unzip, using something like this...

$file = file_put_contents("../data/SomeZipFileLocation.gz", fopen("SomeURL", 'r'), LOCK_EX);

Then you can read the contents like this...

$file = gzopen("../data/SomeZipFileLocation.gz", 'rb');
while (!gzeof($file)) {
print(gzread($file, 4000));
}

This will loop through each of the 4,000 bytes in the file from the gzip and display them.

Using this technique, you won't ever have to manually download and unzip these gzipped files to use the newest version with your code.

Monday, August 27, 2018

Using HTAccess to Redirect All Users (and POST data) to the Same URL

With the Apache .htaccess file, you can control a good number of things on your server.

If you turn on the RewriteEngine, you can have one URL example.com/123, always return the results of another URL, like example.com/index.php?id=123.

To do this, you need to have a .htaccess file in the base directory of your apache htdocs folder. It should start with this...

RewriteEngine On
RewriteBase /

And, it can redirect everyone to index.php with this...

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,NC,L]

You can change index.php to anything you like, of course. Then you can get the information about the original URL by using the $_POST parameters, which you can see with...

print_r($_POST);

Sunday, August 26, 2018

How do I Salt and Encrypt Passwords in PHP?

Salting a password occurs when you add text to a password to make it longer and more complex.

For instance, "myPassWord" would be "myPassWordSomeSalt". Since this is longer, when it is encrypted, it will become a more complex result.

Then when you compare the "salted password" to a user's password, you just append "SomeSalt" to the user's input. Your condition looks like...

if(COMPARE($_POST['password'] . 'SomeSalt', $db['password'])) {...}

While this was useful at one time, this concept of salting is now built-in to passwords in PHP. You can simply do...

$hash = password_hash($password, PASSWORD_DEFAULT);
if(password_verify($password, $hash) {
// password is valid!
}

This saves you time in coding, and also means that a more reliable, mathematically-based password salt is generated and used.

Source: http://php.net/manual/en/function.password-hash.php

Thursday, August 23, 2018

Full UTF-8 Web Application Development - How to Do It Right

With UTF-8 support, you can be guaranteed that any language will work with your code. But there are two fundamental things that you need to make sure happens:

First, convert your database to UTF-8. This is the data part of it.

To convert your database requires changing the default settings and converting the tables themselves. You can change the default settings with...

MyDB@sys mysql> ALTER DATABASE MyDatabase DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

And you can convert your tables with...

MyDB@sys mysql> ALTER TABLE MyTable DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
MyDB@sys mysql> ALTER TABLE MyTable MODIFY MyColumn VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';

Second, send all web pages with a UTF-8 header. This is the networking part of it.

For example, in PHP, to send the UTF-8 header, you will run this command being sending any output to the browser...

header('Content-type: text/html; charset=utf-8');

Every program, protocol, etc., has its exceptions and variations, so these are just the two basics you need to handle.

Wednesday, August 22, 2018

"bind_param() expects parameter 1 to be resource, boolean given" -- Possible Fixes?

Your MySQL and PHP code may be fully and logically thought-out. You may have even tested and verified it worked. But now you have this error:

"bind_param() expects parameter 1 to be resource, boolean given"

Your code probably looks something like this...

$db_link = new mysqli($hostname, $username, $password, $database);
$sql = "SELECT * FROM SomeTable WHERE id = ?";
$statement = $db_link->prepare($sql);
$statement->bind_param($_POST['id']);

How do you fix it? The problem is not with the bind_param() function, it's with the prepare() or the mysqli() functions!

If statement is a boolean, that means it is true or false, and in this case, false means that either mysqli() could not connect to the DB, or that prepare() had a problem.

If mysqli() has a problem, it could be a bad username/password combination, a networking issue, a bad db name, or something else. If prepare() has a problem, it could be a bad query, an unescaped term in the query, or something like that.

You can verify that mysqli() worked, by displaying its result and seeing that it's not false, and similarly with prepare().

Tuesday, August 21, 2018

Should Or Shouldn't I Use the MySQL_* functions in PHP?

There are a number of ways to access your MySQL server from PHP.

The first way, and the one originally taught, was to use the specialized MySQL functions in PHP, such as mysql_query(), mysql_connect(), and mysql_real_escape_string().

However, there are two problems with this function set.

First, it uses escaped strings, which are ultimately unsafer, slower, and less reliable than using Prepared Statements in MySQL.

Second, the developers behind the MySQL_* functions are no longer developing it, they no longer accept feedback on it, and they ask users to move onto something more reliable, with Prepared Statements, for MySQL uses.

This second reason is so strong, that all MySQL_* functions have been removed from PHP version 7.0 and up. Learn to do prepared statements, or these two reasons will perpetually haunt your code.

Monday, August 20, 2018

How do I prevent MySQL Injection with PHP?

We all know that you can make a simple form with some HTML, put together a quick PHP script, build a few MySQL tables, and you have yourself a full, working application in a matter of minutes.

Your PHP may end up initally looking like this...

$sql = "SELECT * FROM SomeTable WHERE id = " . $_POST['id'];

The HTML script would contain the necessary form and input elements, and SomeTable would be in the database. But this creates the possibility of a MySQL injection.

To prevent mysql injection, we send the SQL query and user input in SEPARATE statements, called Prepared Statements. Put a question mark where you want the variable to be...

$db_link = new mysqli($hostname, $username, $password, $database);
$sql = "SELECT * FROM SomeTable WHERE id = ?";
$statement = $db_link->prepare($sql);
$statement->bind_param($_POST['id']);

This will prevent users from submitting malicious data. Imagine, for example, if someone tried to submit an 'id' of value "0 AND DROP TABLES;", which would have a negative consequence on your app.

Thursday, May 30, 2013

Installing Apache, PHP, and ImageMagick together using Linux/CentOS

There is a big disclaimer that should be made to all those about to venture on ImageMagick programming using PHP: the great, vast majority of WAMP (Windows-Apache-MySQL-PHP) servers do not support ImageMagick commands at all, since it is a "different package," and there appears to be no way to install ImageMagick through standard Add/Remove Applications within Linux (as far as standard Debian linux releases go).  It's very easy to get Apache/PHP running in either Windows or Linux with pretty much any standard OS/distro supported so that you can run all of your own code on your own computer.  But that's definitely not the case when you want Imagick to cooperate with your Apache server and your PHP code!

It took me almost an entire week just to get Apache/PHP/ImageMagick working all together nice and happily so that I could run my own PHP code on my own machine (natively, too).  So, I decided to simply write down the steps, to help anyone else out who could need help.

Guide to Building an Apache/PHP/Imagick Server with Linux/CentOS 6.4:::

1. Install CentOS 6.4.  (Theoretically, other versions of CentOS should work as well, but I simply chose the most recent one.)  Also, you can very easily emulate CentOS within Windows (for instance, the unfree choice of VMWare).
2. Install PHP, PHP-Common, PHP-extensions, etc., from standard Application Package Manager ("Add/Remove Programs", usually in system tools somewhere).  (You don't have to worry about Apache, because that comes with CentOS 6.4 anyway.)
3. Open up a terminal and enter admin mode with the command "su".  You'll need a password for this.
4. Enter this command: yum install ImageMagick ImageMagick-devel
5. Enter this command: pecl install imagick
6. Modify php.ini and include the line "extension=imagick.so".  This file is located at "/etc/php.ini" normally.  The line must be exactly inserted in the section of "Dynamic Extensions", which begins with this commented out text:

--------------------------------
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
--------------------------------

Use the "search" feature of gedit to find the text.  Add the extension below the commented out note in this section so that the result looks like:

--------------------------------
;;;;
; Note: packaged extension modules are now loaded via the .ini files
; found in the directory /etc/php.d; these are loaded by default.
;;;;

extension=imagick.so
--------------------------------

Putting the extension directly at the top caused me serious permission issues in running Imagick code.  Also, with CentOS, the permissions automatically disable user control for this php.ini.  Enter the following terminal command: "chown [YOUR-USERNAME] -R /etc/php.ini", without the quotes to get control to modify it.  Note to insert your username where it states "[YOUR-USERNAME]".
7. Enter this command: "service httpd restart", without quotes, from admin mode.  This restarts Apache/PHP/PHP's extensions now that you've installed ImageMagick.  If this gives you an error, just try "service httpd start".

My favorite part about this method is that you can update your system with issuing the "yum update" command and then the "yum upgrade" command -- and the Apache/PHP/Imagick combination will still be working perfectly!  Unlike some other guides out there for this, you don't need to rely on antiquated, unsupported versions that can be nearly impossible to find.  Also, you don't need to worry about the MySQL, Hash, MBString, Exif packages, because they all seem to be installed and properly cooperating with PHP automatically after installing PHP from the Application Manager.  This solution makes everything work well together.

The root directory of your public files is located at /var/www/html/.  Normally, this folder is not owned by the user, so you'll get a permission error when trying to add files or folders to it.  Correct that with entering admin mode in the terminal/command-line window ("su" command) and entering the following command: "chown [YOUR-USERNAME] -R /var/www/html/", without quotes.  Again, replace "[YOUR-USERNAME]" with your actual user name.  (Warning: The first time I did this, I was lazy and entered the command for only the "/var/" folder, which prevented my system ever from booting.  It would always freeze with the notorious and googleable error-message: "Could not update ICEauthority file /var/lib/gdm/.ICEauthority".  So, make sure to change ownership only for "/var/www/html/".)

To view your root directory files as compiled, resultant, PHP pages, open up a browser and enter "127.0.0.1" as the address.  So, a file in your root directory would be accessed at the following URL in your browser: http://127.0.0.1/your.file.php .  If you get a "could not connect" error message, try the command "service httpd start" at the terminal window from admin mode.  (You have to start this service manually every time the machine boots, although there's plenty of ways to automate it.)

I hope this helps!  I tried a hundred different guides on getting Apache/PHP/Imagick to work together and none of them worked.  Don't give up!  ImageMagick is a package of really neat imaging functions!

Monday, July 2, 2012

Image Rendering Intent in the ImageMagick Package of PHP

The Rendering Intent variable exists in ImageMagick to provide support for ICC Color Profiles.  There are five results that one can expect to get from the getRenderingIntent function, which are the predefined constants for Rendering Intent within ImageMagick.  These values look like "imagick::RENDERINGINTENT_UNDEFINED", with "_VALUE" values of: undefined, saturation, perceptual, absolute, and relative.  Printed out, Undefined is 0, Saturation is 1, Perceptual is 2, Absolute is 3, and Relative is 4.

The official ImageMagick documentation provides good light on what these values indicate. ( http://www.imagemagick.org/RMagick/doc/constants.html#RenderingIntent )  Undefined means "no intent," Saturation means "A rendering intent that specifies the saturation of the pixels in the image is preserved perhaps at the expense of accuracy in hue and lightness," Perceptual Intent means "A rendering intent that specifies the full gamut of the image is compressed or expanded to fill the gamut of the destination device. Gray balance is preserved but colorimetric accuracy might not be preserved," Absolute Intent means "Absolute colorimetric," and Relative Intent means "Relative colorimetric."

Every time I ran this function, it always produced the same result: #2, indicating Perceptual Intent.  But this makes sense, since the ImageMagick documentation notes about the Rendering Intent, "Typically, the user or application will set the rendering intent dynamically at runtime or embedding time."  The ImageMagick documentation also recommended the following link to better understand Rendering Intent in terms of Colorspace Profiles: http://www.cambridgeincolour.com/tutorials/color-space-conversion.htm .

Some sample code :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Imagick Type
        // ---------------------------------------------

    $imagick_type = new Imagick();
   
        // Open File
        // ---------------------------------------------
       
    $file_to_grab = "image_workshop_directory/test.jpg";
   
    $file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
   
        // Grab File
        // ---------------------------------------------

    $imagick_type->readImageFile($file_handle_for_viewing_image_file);
   
        // Get Rendering Intent Values
        // ---------------------------------------------

    $imagick_rendering_intent = $imagick_type->getImageRenderingIntent();
   
    switch($imagick_rendering_intent)
    {
        case '0':
            $image_rendering_intent_evaluated = "Undefined";
            break;
           
        case '1':
            $image_rendering_intent_evaluated = "Saturation";
            break;
           
        case '2':
            $image_rendering_intent_evaluated = "Perceptual";
            break;
           
        case '3':
            $image_rendering_intent_evaluated = "Absolute";
            break;
           
        case '4':
            $image_rendering_intent_evaluated = "Relative";
            break;
    }
   
        // Print Rendering Intent Values
        // ---------------------------------------------
   
    print("# $imagick_rendering_intent - $image_rendering_intent_evaluated");

?>

Official Function Page: http://www.php.net/manual/en/imagick.getimagerenderingintent.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Sunday, July 1, 2012

Image Orientation in the ImageMagick Package of PHP

Using the getImageOrientation function, you'll get the Orientation value for an image as defined within the EXIF file format.  That means you will get back an integer representation one of the Orientation constants for ImageMagick, which looks like " imagick::ORIENTATION_UNDEFINED", with "_VALUE" values of: undefined (0), topleft (1), topright (2), bottomright (3), bottomleft (4), lefttop (5), righttop (6), rightbottom (7), and leftbottom (8).  When printed out directly, these predefined constants produce the number in parenthesis.  The undefined being set to 0 makes sense, since -- according to Wikipedia -- EXIF allows for eight possible values for an image (and not every image has a set of EXIF properties).

The EXIF Orientation is also called "the Rotation," again, according to Wikipedia: http://en.wikipedia.org/wiki/Exchangeable_image_file_format .  What's the point of that?  According to the official ImageMagick documentation, it's to rotate a photograph so that it is properly oriented after the shot.  This really seems to be a camera thing, since the ImageMagick documentation mentions: "If you pointed your camera almost straight up or down, the EXIF orientation setting may not resolve correctly. The same goes for angled or slanted shots. The orientation (and cameras) just have no senses for these situations." ( http://www.imagemagick.org/Usage/photos/ )

If you're having trouble getting this function to show the value for Image Orientation, then use the function and parameters of getImageProperties('*', FALSE); .  This produces an array of all properties associated with an image, and one of them will have the key value of exif:Orientation.  If it doesn't, then that means you will be getting back a zero from this function, indicating an "Undefined" orientation.

Some sample code :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Imagick Type
        // ---------------------------------------------

    $imagick_type = new Imagick();
   
        // Open File
        // ---------------------------------------------
       
    $file_to_grab = "image_workshop_directory/test.jpg";
   
    $file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
   
        // Grab File
        // ---------------------------------------------

    $imagick_type->readImageFile($file_handle_for_viewing_image_file);
   
        // Get Orientation Values
        // ---------------------------------------------

    $imagick_orientation = $imagick_type->getImageOrientation();
   
    switch($imagick_orientation)
    {
        case '0':
            $imagick_orientation_evaluated = "Undefined";
            break;
       
        case '1':
            $imagick_orientation_evaluated = "Top-Left";
            break;
       
        case '2':
            $imagick_orientation_evaluated = "Top-Right";
            break;
       
        case '3':
            $imagick_orientation_evaluated = "Bottom-Right";
            break;
       
        case '4':
            $imagick_orientation_evaluated = "Bottom-Left";
            break;
       
        case '5':
            $imagick_orientation_evaluated = "Left-Top";
            break;
       
        case '6':
            $imagick_orientation_evaluated = "Right-Top";
            break;
       
        case '7':
            $imagick_orientation_evaluated = "Right-Bottom";
            break;
       
        case '8':
            $imagick_orientation_evaluated = "Left-Bottom";
            break;
    }
   
        // Print Orientation Values
        // ---------------------------------------------
   
    print("# $imagick_orientation - $imagick_orientation_evaluated");

?>

Official Function Page: http://www.php.net/manual/en/imagick.getimageorientation.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Saturday, June 30, 2012

Difference Between the Hash() and Hash_File() Functions in PHP

The Hash_File() function returns the same value as if the function Hash() had been performed on the same exact piece of data.  At first, I was uncertain if Hash_File() used the filename, or even the permission settings, when defining the data to be hashed for the given algorithm.  If it did work that way, then that means the same exact files would have different HASH values when you moved or renamed them on your system.  Anyway, fortunately, it does not work that way.  Hash() and Hash_File() produce identical results for the same pieces of data.  This is also true for the relationship between the Hash_HMAC() and Hash_HMAC_File() functions: the same pieces of data, the same keys, produce identical results.  It was a wise, design principle.

Some sample code to demonstrate this principle :

<?php

            // Author: holdoffhunger@gmail.com

        // Preset Data
        // ------------------------------------------------
       
    $test_data = "php-hashing";
    $test_file = "test.txt";
    $test_file_read = file_get_contents($test_file);
   
        // Hash Data
        // ------------------------------------------------
   
    $test_data_hash = hash("md2", $test_data, FALSE);
    $test_file_hash = hash_file("md2", $test_file, FALSE);
   
        // Print Hash Results
        // ------------------------------------------------
   
    print("Data Hash ($test_data): $test_data_hash<br><br>");
    print("File Hash ($test_file_read): $test_file_hash");
   
?>

    Expected Results
    ..................................
   
Data Hash (php-hashing): 457d84e1d69e519a7b73348db21477d3

File Hash (php-hashing): 457d84e1d69e519a7b73348db21477d3

Official Function Page: http://www.php.net/manual/en/function.hash-file.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Friday, June 29, 2012

Using the MHash Function to Create HMAC Hash Results in PHP

The MHash function here lists one disclaimer at the top when providing a key to the mhash function : "Not all algorithms supported in mhash can be used in HMAC mode."  So, what algorithms blow up and what do fine when it comes to doing keyed, HMAC hashing?  The destructive ones are: Adler32, CRC32, CRC32B, and GOST.  These are the first four, predefined constants listed with the MHash Application Package: http://www.php.net/manual/en/mhash.constants.php .  Providing one of these algorithms with an HMAC key (of string-length greater than one) creates the following error message: "Warning: mhash() [function.mhash]: mhash initialization failed in [(folder-location)] on line 181".  If you really want to use these algorithms in creating your HMAC hashes, the function Hash_hmac() from the HASH-Message Digest Framework package is capable of doing that perfectly.

Again, that is if the string length is greater than one.  Why string length greater than one?  Well, if the key value is blank, it is ignored as a parameter altogether.  So, if you feed the mhash function an algorithm that is not compatible with HMAC hashing and an HMAC key that's blank (""), it will work the same as if it had received no HMAC key at all.  This is different from the way the Hash_hmac() function of the HASH-MDF works.  In the case of the Hash_hmac() function, feeding a blank HMAC key will use that blank key in generating the HMAC hash.  Even with functions that can do HMAC hashing, like MD5 or SHA1, if the MHash() is given a blank HMAC key, it will ignore the key and just return the results of standard, non-HMAC hashing.  It's probably not wise to use a blank HMAC key anyway, but it's good to know that the hashing algorithm changes altogether if the provided HMAC key is blank.

Some sample code to demonstrate :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Preset Data
        // ---------------------------------------------------

    $string_to_hash = "The hash_hmac() function better to use for these purposes.";
    $blank_hmac_key = "";
   
        // MHash - Hashing With and Without HMAC Parameter
        // ---------------------------------------------------

    $mhash_result_with_hmac_parameter = bin2hex(mhash(MHASH_CRC32, $string_to_hash, $blank_hmac_key));
    $mhash_result_without_hmac_parameter = bin2hex(mhash(MHASH_CRC32, $string_to_hash));
   
        // MHash - Hashing With and Without HMAC Parameter
        // ---------------------------------------------------

    $hash_result_with_hmac_parameter = hash_hmac("crc32", $string_to_hash, $blank_hmac_key);
    $hash_result_without_hmac_parameter = hash("crc32", $string_to_hash);

        // Print Results
        // ---------------------------------------------------

    print("MHASH (CRC32 Algorithm) With Blank HMAC Key: $mhash_result_with_hmac_parameter .<br>");
    print("MHASH (CRC32 Algorithm) Without HMAC Processing: $mhash_result_without_hmac_parameter .<br><br>");

    print("HASH (CRC32 Algorithm) With Blank HMAC Key: $hash_result_with_hmac_parameter .<br>");
    print("HASH (CRC32 Algorithm) Without HMAC Processing: $hash_result_without_hmac_parameter .");

?>

    Results :
    ...................................

MHASH (CRC32 Algorithm) With Blank HMAC Key: f665c094 .
MHASH (CRC32 Algorithm) Without HMAC Processing: f665c094 .

HASH (CRC32 Algorithm) With Blank HMAC Key: 3041f4f8 .
HASH (CRC32 Algorithm) Without HMAC Processing: f665c094 .

Official Function Page: http://www.php.net/manual/en/function.mhash.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php