Storing passwords with Bcrypt [PHP]

It’s always a hard decision how one should store a password in PHP. Mostly you would stick with md5 or sha1, but there’s a big problem with them: speed. They are designed to quickly hash large amounts of data, so you can e.g. test if a big file was downloaded correctly. So that wouldn’t be a good way to store your passwords, because they can be cracked easily if your database got hacked.

I ran a short test, it takes my iMac only ~1.3 seconds to hash 1,000,000 passwords with md5, for sha1 it’s ~1.4 seconds. So to crack a weak, 6 character long password with a brute-force attack, it takes me at most 15 minutes. That’s quite bad, hugh? Therefore, we have to use an algorithm that is much more complex. Bcrypt is designed with exactly that problem in mind, and it’s quite simple to use with PHP. Continue reading

Filling Circle Animations [JS]

For my latest project, my designer decided that he wanted the login form with some nice circle animations. So if the user would submit the form, there is a filling circle while checking the password. There is no CSS solution out there, or at least no one that is more than an experiment with CSS3. So we have to use the <canvas> element in order to achieve this (I played around with SVGs for a while, just forget it).

In order to animate the circle, we first need a function to set the circle to a given state. The state is given in percent, so we first need to convert it to radians like this (a zero angle would be horizontal, but we want to start the animation at the top, so we substract 1/2π): Continue reading

Return to a specific AJAX-produced state with Hashtags [jQuery]

When I was working on my latest project for CodeCanyon, I encountered a problem: The script loads a list of files via AJAX (there are many different lists), and when you click on a file, it is displayed on a separate page. Now, when you hit the back Button on the new site, the file list isn’t loaded automatically.

The solution for this problem is quite simple: You just append a hashtag and the ID of the list to the back-URL, like this: http://path.to/script#list9. That value can be retrieved in Javascript in the “window.location.hash” variable. So now, when the user clicks the back button, we know which list he loaded before. To restore the state, we had to load the contents based on the ID.

But there’s a much simpler method: We can also simulate the click event that the user would have performed if he loaded the files manually. That’s pretty simple with jQuery:

$(document).ready(function(){          // We will want to load the files when the page is ready
	if( window.location.hash != "" ) { // Perfom only if we actually have a hashtag
		$( window.location.hash + ' a.button' ).click();
	}
});

Note that window.location.hash already includes the hashtag, so we don’t have to add one so jQuery finds the element. Then we just perform the .click() method on it, and we’re done!

Hint: Of course the code above is ready to be copy-pasted into your project!

Filesize problems [PHP]

When working with large files in PHP, you will at some point get in trouble with the limits of the filesize() method. Basically, there are two big problems: First some 32-bit integer stuff (I don’t want to focus on the problem, but the solution) with Linux for files > 2GB and Windows with files > 4GB.

Luckily, for both of this scenarios, there exist solutions. The filesize() manual is very handy, though most of the users seem to specialize on the Windows problem. I read through almost all comments and created this quite bulletproof function:

function size( $path ) {
	$size = filesize( $path );

	if( $size === false )
		return false;

	if ( $size < 0 )
		if ( ! strtoupper( substr( PHP_OS, 0, 3 ) ) == 'WIN' )
			$size = trim( `stat -c%s $path` );
		else {
			$fsobj = new COM( "Scripting.FileSystemObject" );
			$f = $fsobj->GetFile( $path );
			$size = $f->Size;
		}

	return $size;
}

First, we try to get the file size normally and check for errors. Then, only if filesize() failed and produces something strange, we go a step further.

We now check on which operating system PHP is running. On non-windows systems, we determine the size via the “stat” command (commands in apostrophes are run in the command line). We trim any whitespace and save it. On Windows, we can use the more advanced FileSystemObject. We simply pass him the path to the file and it returns us the right size. And that’s it!

Hint: Of course the code above is ready to be copy-pasted into your project!

Beautify Wikipedia [jQuery] [Chrome Extension]

A big problem with Wikipedia is its readability on large screens. The lines are just too big and the font isn’t very nice either. What we are gonna do today is write a simple Chrome Extension that helps us with this problem.

To all non-coders: If you only want the final Chrome Extension, just scroll down to the bottom of the article and click “beautify-wikipedia.crx”.

Wikipedia on a 2560px wide monitor

Continue reading

Human readable file size [PHP]

There are definitely many, many code snippets out there, which calculate a file size in PHP to a human readable form. But for a reason I don’t understand, people are doing much more work than they had to do.

E.g. if we look at PHPs filesize() Manual, the methods described there are either very long and inconvenient (like the first two), or you’re not quite sure what they will output (the third one). But let’s face it: What do we really have to do? We just get the files size, divide by 1024 until the number is small enough and then append the right unit. So here’s my solution:

function size( $path ) {
	$size = filesize( $path );

	if( $size === false )
		return 'Error';

	$index = 0;
	while( $size > 500 ) {
		$index ++;
		$size /= 1024;
	}

	$units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );

	return round($size, 1) . $units[$index];
}

What I added in line 4 is just a quick check if there were any errors, e.g. the file doesn’t exist. We remember how often we divided until the size was smaller than 500 (I think it’s quite nice, so it would be 0.5GB rather than 500MB. But you can change it to whatever you want) in the $index variable. Then we can append the unit based on the $units array to the rounded value and we’re done!

Hint: Of course the function above is ready to be copy-pasted into your project.