Aug 11 2009

Create A Simple Captcha With PHP and GD

Everyone hates captchas. I know I do. It sucks but they are a necessary evil. Most captchas are difficult (sometimes impossible) to read and they will consistantly drive visitors from your site. I’ve been on sites where the captcha was so hard to decipher that I’ve never gone back.

During the development of a new site I was forced to create one of these evil entities. It was surprisingly simple and painless. The captcha that I outline here is very, very simple and should never be used in production without a fair amount of tweaking.

Having developed my site using php I naturally turned to the GD library.

Firstly I generated a random string to display on the captcha :


//generate a random alphanumeric string of a specific length
function gen_random_string($length) 
{
  $characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWZYZ".
        "abcdefghijklmnopqrstuvwxyz";
  $real_string_length = strlen($characters) - 1;
  for($p=0;$p<$length;$p++)
  { $string .= $characters[mt_rand(0, $real_string_length)]; }
  return $string;
}

//add to session array so other scripts can access it for the comparison
$_SESSION['image_text']= gen_random_string(8);

//split into character array - str_split only works in PHP 5
$text_array = str_split($_SESSION['image_text']);


Now that I have my string I need to create the image. Make sure that GD is installed on your php apache server.

//create the image with a background image
$NewImage =imagecreatefrompng("bg1.png");
$cntr = 0;
foreach($text_array as $letter)
{
  //generate a random color for each letter
  $r = rand(0,200);
  $g = rand(0,200);
  $b = rand(0,200);
  $textcolor = imagecolorallocate($NewImage, $r, $g, $b);

  //random horizontal spacing
  $spacing = (rand(5,10)+($cntr*10));
  
  //add the character to the image
  imagestring($NewImage, 5, $spacing, rand(0,10), $letter, $textcolor);
  $cntr++;
}


The code above will generate a GD captcha image with random coloring and random horizontal and vertical spacing on top of a background image.
Now we just need to output it.

//output the headers than the image as a PNG
header('Content-type: image/png');
header('Cache-Control: max-age=0');
header('Expires: '.gmdate('r',time()-3600*24*365));
header('Pragma:');
ImagePNG($NewImage);
imagedestroy($NewImage);


So if I called this file simple-captcha.php I could call it with this html:

<img id='captcha' name='captcha' src="simple-captcha.php">


Here is what it looks like :

This captcha can be strengthened by using other GD image functions such as imagefilledellipse and imageline to create artifacts in the background. It also helps to use different fonts and to change the angle of the letters.

Share

Aug 4 2009

Personal Computers In 1979. The Apple II

The Apple II was the first really successful mass produced microcomputer. Introduced in 1977, (the ad below is from 1979) this machine was a major technological advancement over its predecessor. By the end of it’s production in 1993 there were about five to six million produced and sold. Anyone that grew up in the 80’s or 90’s may recognize this machine from their education as it was the standard computer in American education.

The Apple II didn’t really have an operating system as we know them. It had a built-in BASIC interpreter contained in ROM. Any games or educational software came on 5¼-inch floppy disks that booted directly on the hardware. This computer was able to run DOS (an Apple specific flavor) and CP/M (which is an old school operating system).

The original Apple II could hold a whopping 48 kilobytes of RAM although it only came with 4. It ran at 1 MHz and had an audio cassette interface for loading programs and storing data. The video controller displayed 24 lines by 40 columns of monochrome, upper-case-only text on the screen, with NTSC composite video output suitable for display on a TV monitor, or on a regular TV set by way of a separate RF modulator. The original retail price of the computer was US$1298[5] (with 4 kB of RAM) and US$2638 (with the maximum 48 kB of RAM). An external 5¼-inch floppy disk drive, the Disk II, attached via a controller card that plugged into one of the computer’s expansion slots (usually slot 6), was used for data storage and retrieval to replace cassettes.


Apple II Advertisement 1979


Apple II

Information and second picture came from Wikipedia.

Share

Jul 28 2009

JavaScript innerText and textContent

I was having an issue with the javascript innerText property today. I was to lazy to convert the legacy code that I was working on to use proper DOM so I did some reading on the issue.

Turns out that FireFox doesn’t use innerText at all. Apparently the proper DOM property to use is textContent. textContent does basically the same thing as innerText.

A not so pretty solution to this issue is to check at the start of the script whether the browser supports innerText or textContent. I found a few resources that allowed me to copy and paste a few lines to make everything work.

This one which I found on coderlab is a little bulky but it gets the job done. It checks which property is available and then forces the programmer to check that flag every time he wants to use the property.


var hasInnerText =
(document.getElementsByTagName("body")[0].innerText\
 != undefined) ? true : false;
var elem = document.getElementById('id');
if(!hasInnerText){
    elem.textContent = value;
} else{
    elem.innerText = value;
}

This is the method I actually used. I just or’d the two different properties together and it seemed to work. I guess one will always be undefined.


var message = elem.innerText || elem.textContent || "";

At least FireFox is following the standards unlike Internet Explorer which always needs special css and javascript. Making everything work in Internet Explorer always adds hours onto development time…

Share

Jul 4 2009

Star Wars Demotivational Posters

those were the droids you were looking for

Ignorance. Sometimes it

Share

Jul 1 2009

Decode Obfuscated WordPress Strings Which Use eval, gzinflate, And base64_decode.

I’ve been using wordpress for awhile and it seems that whenever I find a useful plugin or theme on the web the author always seems to embed some affiliate link or some other garbage on my main page. Usually they make sure that these links show up on every page and sometimes they even make other features of the software depend on it. Usually when I try to edit out the code it’s not as easy as removing an anchor or a bit of javascript. They always seem to obfuscate what they are doing as much as possible.

The most popular way to do this is to use a combination of gzinflate, base64_decodes, eval, and str_rot13. For most users this is really difficult to decode to figure out what is really going on. I wrote this function to hopefully make peoples lives easier (or harder, depending on who you are).
Usually the obfuscated code is written in the wordpress add-on like this :


$coded_string = "eval(gzinflate(base64_decode('FZfFDs..sdff/7nr/8B')));"

If your string looks like that then the function that follows should take decode it and return the html code pretty easily.

function decode_goofy_string($coded_string)
{
  while(preg_match("/eval\(gzinflate/",$coded_string)) 
  {
    $contents=preg_replace("/<\?|\?>/", "", $coded_string); 
    eval(preg_replace("/eval/", "\$coded_string=", $coded_string)); 
  }
  
  return trim($coded_string);
}

This function is pretty straight forward but if anyone has any troubles then leave a comment or send me an email at cody@codytaylor.org

Share

Jun 29 2009

WordPress Shortcode To Generate A TinyURL For Any Post

TinyURLs can be very useful when you have a long url to type into something like an iphone or some other mobile device where the keyboard is rather tedious. On a few of my sites I was looking for a way to automatically generate a tinyURL with the least amount of effort. Since I use wordpress for most of them I decided to go with a shortcode.

Shortcodes seem to be gaining a fair amount of attention in the wordpress community and with good reason. The Shortcode API, which was new in wordpress 2.5, is a simple set of functions for creating macro codes for use in your posts. Shortcodes are written by providing a handler function and they accept parameters too. Here is a wordpress shortcode to generate a tinyURL for a post.


//Generate Tiny URLS For A Post 
function get_tiny_url($arguments)
{
  if(empty($arguments))
    $url = get_permalink($post->ID);
  else
    $url = urlencode($arguments['url']);
  if($url)
    {
      $tiny_url = 'http://tinyurl.com/api-create.php?url='.$url;
      $new_url = file_get_contents($tiny_url);
    }
    else
      $new_url = "Error";
    return $new_url;
}

add_shortcode('small_url', 'get_tiny_url');

If the url parameter is not defined then the function will attempt to use the wordpress function get_permalink($post->ID) which will return the current posts url. Also you can pass in a parameter if you want to show a tinyURL to another location. Using curl instead of file_get_contents would probably be faster but I didn’t want to make the example to long. The add_shortcode function is what tells the API to use the get_tiny_url function when it encounters the small_url shortcode. Note that this will call on the tinyurl api every page view so it would probably be prudent to set the tiny urls in the database so you only have to check once on a production site although I’m not sure if they expire or not.
This shortcode can be called in the post by typing :

[small_url]  // or
[small_url url='http://codytaylor.org']

Share

Jun 26 2009

Make Your PHP Faster

I was reading about some php performance tips at work today and decided to throw together some of the ways to make your php site faster.

Here’s a couple of short tips to avoid making your site lag for the user:

  1. Unset your variables. This frees up a surprising amount of memory
  2. Use memcache
  3. Turn on apache’s mod_deflate
  4. If your database is local then close your connections when you’re done with them
  5. If your database is remote then use persistant connections
  6. Don’t use functions inside of a for loop control expression unless absolutely necessary. Example :
    
    for($i=0;$i<some_big_calculation(20);$i++)
    

    The some_big_calculation function will be called every iteration.
  7. Use string concatenation instead of embedding variables in strings.
    
    $some_string = "asdf $asdf2 asdf"; //bad
    $some_string = 'asdf '.$asdf2.' asdf'; //good
    
  8. When including files, use at least a relative path so PHP doesn’t have to look in the entire path.
    
    include("./some_file.php"); // looks in the current directory
    include("wrong.php"); // searches every directory in the path
    
  9. Try not to use include_once or require_once. They are more expensive and it really isn’t that hard to only include files once
  10. Not everything needs to be an object. There is a fair amount of overhead when doing everything OOP.
  11. Use output buffering to make everything seem faster.

Hopefully I didn’t miss any of the big ones.

Share

Jun 25 2009

What Is Antenna Gain?

I didn’t know enough about antenna gain to define it if someone asked me to so I did some research. Gain itself seems to be a tricky term to define, so I’m going to have to explain a few other things along with it.

Antenna gain is basically measure of the effectiveness of a directional antenna as compared to a standard nondirectional antenna.

One of the major parameters used in analyzing the performance of radio frequency (RF) communications links is the amount of transmitter power directed toward an RF receiver.

This power is derived from a combination of:
1 – Transmitter power
2 – The ability of the antenna(s) to direct that power toward an RF receiver(s).

Directivity
The directivity of the antenna is determined by the antenna design. Directivity is the ability of an antenna to focus energy in a particular direction when transmitting or to receive energy better from a particular direction when receiving. To determine the directivity of an antenna, we need a reference antenna with which to compare our antenna’s performance.

Over the years there have been several different reference antennas used. Today an isotropic radiator is preferred as the standard antenna for comparison. The isotropic antenna transmits equal amounts of power in all directions (like a light bulb).

To increase the directivity of a bulb’s light (the antenna’s energy), similar to a flash light or automobile head lamp in this example, a reflector (antenna) is added behind the bulb. At a distance, in the light beam, the light bulb now appears to be much brighter. The amount that the bulb appears brighter compared to the bulb without a reflector is the directivity of the reflector (antenna).

When the directivity is converted to decibels we call it the antenna gain relative to an isotropic source (dBi). Typically the higher the gain, the more efficient the antenna’s performance, and the farther the range of the antenna will operate. Roughly for every 6 dBi in gain, you double the range of the antenna.

It should be noted that many issues need to be considered when selecting the “best” antenna for the application, and you should discuss any antenna selection with someone knowledgeable in RF radiation and antenna performance.

So a better definition of antenna gain is:
A relative measure of an antenna’s ability to direct or concentrate radio frequency energy in a particular direction or pattern. The measurement is typically measured in dBi (Decibels relative to an isotropic radiator) or in dBd (Decibels relative to a dipole radiator).

Share

Jun 22 2009

Update Twitter using Command Line, Javascript, Or PHP.

Everyone seems to be all about Twitter so here’s some simple examples of how to update your Twitter status from a command line prompt, web server or simple html web site. These three examples require curl so install it if you don’t already have it. For these examples I’ll be using my Twitter user name ‘codytaylor1234’. My password is not ‘mypassword’ so make sure you put in your own information.

The easiest way to update your Twitter account is to just call curl from the command line with this command.


curl --basic --user "codytaylor1234:mypassword" --data-ascii 
"status=This Twitter update brought to you by curl on the command line" 
"http://twitter.com/statuses/update.json"


To update your Twitter status with PHP you are going to want to do the same sort of thing but with a bit more typing.

<?php
$username = 'codytaylor1234';
$password = 'mypassword';

$update = 'This Twitter update is from a php script using curl';

$url = 'http://twitter.com/statuses/update.json';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$url");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "status=".$update);
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);
$result = curl_exec($ch);
curl_close($ch);

if($result)
    echo 'success';

?>;

Since a cross-domain request in Javascript isn’t really an option we have to create a proxy using PHP in order to authenticate the user on the Twitter API. If anyone knows an easy way authenticate a Twitter user using only javascript I’d love to hear it. Anyway if we replace a small amount of code in the above example and put it in a file then we can use a simple ajax request to update our Twitter status. So the new PHP file would be:


<?php
$username = $_POST['username'];
$password = $_POST['password'];

$update = $_POST['update'];

$url = 'http://twitter.com/statuses/update.json';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$url");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "status=".$update);
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);
$result = curl_exec($ch);
curl_close($ch);

?>

For this example I called that php file ‘twitter-update.php’. Now that we have our simple proxy we can update our twitter status with a simple html form and a little ajax. I used the prototype framework for my javascript.


<script src="includes/prototype.js" type="text/javascript">
<script type='text/javascript'>
function update_twitter()
{
  var param_string = "username="+$('username').value+"&password="+
        $('password').value+"&update="+$('update').value;
  alert(param_string);
  var options = {
    method: "post",
    parameters: param_string,
    onSuccess: function (xhr, Json) {
      alert("Response received successfully.");
    },
    onFailure: function (xhr, Json) {
      alert("Request was unsuccessful.");
    }
  };
  
  var oRequest = new Ajax.Request("twitter-update.php", options);
}

</script>

Obviously this is for example purposes only and if you’re actually using it for production then you should edit it a lot. Now for the last little bit here’s the simple html form that starts it all.


User Name : <input type='text' id='username' value='codytaylor1234'><br>
Password  : <input type='password' id='password' value='mypassword'><br>
New Status : <input type='text' id='update' 
value='Twitter Update from html/javascript/php'><br>
<input type='button' value="Update Twitter" onclick='update_twitter();'>

Share

Jun 21 2009

Left 4 Dead Authoring tools/SDK Finally Coming Out

It seems that the guys at valve are finally going to allow community content to be played by the mainstream user. Along with a non beta version of the sdk that is said to release next week the l4d devs are also going to be overhauling the matchmaking system to support “Add-on Campaigns” which will allow you to select campaigns that you have installed.

Because of the recent announcement of Left 4 Dead 2, a lot of fans are wondering whether it’s worth the trouble creating any custom content because the it may not work with the new game. I found this quote from one of the writers for most of Valve’s games which addresses the issue.

Chet_Faliszek wrote:One thing we do know for sure is we want to make sure that everyone making a Left 4 Dead 1 map now or campaign now it’s still going to work in Left 4 Dead 2. You will be able to start Left 4 Dead 2 up, you will have the new creatures automatically, you’ll have the new weapons you will have all of that in the world, if you want to do some of the new director stuff or some of the new ways we control item placement you can go re-do it and add that, but you can also just leave it the exact same way and it will work.

When I was first reading about this on the Left 4 Dead Blog I started thinking of playing de_dust with hordes of zombies which was apparently done in the demo but never released. But then I remembered that I only have the game for XBOX 360. In the few news reports that I’ve read I haven’t seen any mention at all of XBOX changes. If you read that blog Yasser Malaika talks about how easy it will be to install the add-on by double clicking the VPK file. More than likely Microsoft will make me pay for every custom map that is freely available for the PC version.

Share