Zend Certified Engineer

phpguru.org

Quality PHP, Javascript and C# code
Download RGraph: HTML5 canvas graph library... Home ~ Downloads ~ FAQs ~ Licensing
RSS Feed RSS Feed
Follow me on Twitter Follow me on Twitter

Articles

HTML5

Javascript

PHP5

PHP4


Bookmark with delicious Stumble! this site tweet this site

TextualNumber

So. What is it? A class (PHP5 only) which converts numbers to words. Funky huh? And useful for what exactly? Well, how about preventing blog spam? Allow me to elaborate...

Ever since I read an article on the PEAR package Text_CAPTCHA, I've been thinking about potential methods for protecting forms from automated submissions. An example of where you wouldn't want this is the previous problem of blog comment spam. Now, Text_CAPTCHA is a fine method for doing this, however, I wanted to be different.

There are, of course, ways around generating the CAPTCHAs on the fly. One possibililty is the use of a script to pregenerate a number of images and store them on disk, ready for use. This you could do either on a rolling basis, so that new images are continually being created as old ones are used up. Or you can generate a fixed, large amount of images and use them at random. The latter is more efficient, load wise, however you need to generate a lot of images to prevent brute force style attacks.

Still, not a particularly great solution IMO. There are other options. Figlet for example. This is a program for generating ASCII art style text, from normal ASCII text input. See:

shell> figlet php
       _           
 _ __ | |__  _ __  
| '_ \| '_ \| '_ \ 
| |_) | | | | |_) |
| .__/|_| |_| .__/ 
|_|         |_|

Very cute huh?

Now this would be perfect for preventing spammers and their automated scourge, as it would be hard for a computer to interpret the output, especially when you factor in the various fonts available for the output. It would go a little something like this:

However (naturally...), I am unable to find a figlet library (libfig? :) ) which would be necessary to create a PHP extension (my C leaves a lot to be desired so creating one is, uh, not an option). Of course you don't need a PHP extension to be able to use figlet - you could quite conceivably use shell_exec() to run the figlet binary and capture the output, as above. Thing is, this forking of a new process will eventually cause performance issues on high traffic sites, just as dynamically generating CAPTCHA images would (though possibly to a lesser extent).

So now we come to the purpose of this article. TextualNumbers. By using this library to convert a random number to its textual representation, you have another method of protecting yourself against automated form submissions. The process goes very much the same as above with figlet:

Example:

<?php
    
    
require_once('TextualNumber.php');

    list(
$number$text) = TextualNumber::Get();
    
    
$_SESSION['form_number'] = $number;
    
    
showForm();
?>

Obviously a little basic, but you get the general gist. If you want to see some sample output, try here. The advantage with this method is that no external program needs to be used, and no image needs to be generated, so it's fast. However it's not infallible. If you have a determined attacker, then it is entirely possible for them to reverse the process and convert the number back, however it's unlikely. Even so, you could use an obsfuscation technique to try and further prevent auto recognition:

None of these techniques are particularly difficult to subvert, but hey, every little helps. Two things that should be noted also are that the conversion process uses the American style of suffixs. This means that a billion is classed as having nine zeros, a trillion 12 zeros, and so on. And, I can imagine that people will have trouble converting textual versions of numbers to integers, so it's probably wise to stick to smaller numbers, eg 0 - 999,999.

Lastly, the range of the code, is -999999999999999999 to 999999999999999999. Though you could add decimals to that too I guess. If you need a number bigger than that, then bully for you. Though it is feasible to extend this range, quite simply.

Function Reference

You can get the code here.

Function Description
TextualNumber::Get() Returns an indexed array of a randomly generated number, and it's textual equivalent.
TextualNumber::GetText(string $number) Returns a string of the textual representation of the given number. The number should be supplied to the function as a string ideally, to allow for large numbers.
TextualNumber::GetCurrency(string $number, string $major, string $minor) This function returns a textual representation of the given number, however with allowances for it being a currency. Eg instead of "1 point four three", "1 pound and forty-three pence" would be returned. The word "pound" can be substituted by supplying the second argument, and the word "pence" by supplying the third argument.

That's it. Enjoy.



RGraph: HTML5 canvas graph library

Example graph made using RGraph

If you're interested in web development, then you may also be interested in RGraph: HTML5 canvas graph library. It uses HTML5 features to produce a wide variety of graph types. Because it moves the creation of graphs from the server to the client, it can significantly reduce the load on your server and your bandwidth usage.