jQuery Real Person

A jQuery plugin that enhances an input field to help reduce automated form submission. If you find this plugin useful please vote for it on the jQuery site.

The current version is 1.0.1 and is available under the GPL and MIT licences. For more detail see the documentation reference page. Or see a minimal page that you could use as a basis for your own investigations.

Default Settings

This plugin is designed to help overcome automated form submission by requiring a "real person" to identify text made up of dots. The entered value is compared on the server with the generated value to determine whether processing should continue.

The real person functionality can easily be added to an input field with appropriate default settings.
You can also remove the real person functionality if it is no longer required.

Default real person:   

 

$('#defaultReal').realperson();

$('#removeReal').toggle(function() {
		$(this).text('Re-attach');
		$('#defaultReal').realperson('destroy');
	},
	function() {
		$(this).text('Remove');
		$('#defaultReal').realperson();
	}
);

You can override the defaults globally as shown below:

$.realperson.setDefaults({length: 5});

Processed fields are marked with a class of hasRealPerson and are not re-processed if targetted a second time.

Options

Customise the real person functionality through additional settings.

Different length:

$('#lengthReal').realperson({length: 8});

Include numbers:

$('#numberReal').realperson({includeNumbers: true});

Regenerate instructions:

$('#instructReal').realperson({regenerate: 'Try again'});

Server-side Implementations

To complete the form processing on the server, you compare the hash value computed from the text entered by the user with the hash value generated on the client. If the two match, then you have a "real person" submitting the form and can continue.

The following server side implementations of the hash algorithm are available:

PHP

function rpHash($value) {
	$hash = 5381;
	$value = strtoupper($value);
	for($i = 0; $i < strlen($value); $i++) {
		$hash = (($hash << 5) + $hash) + ord(substr($value, $i));
	}
	return $hash;
}

if (rpHash($_POST['realPerson']) == $_POST['realPersonHash']) {
	...

PHP - 64 bit

function rpHash($value) {
	$hash = 5381;
	$value = strtoupper($value);
	for($i = 0; $i < strlen($value); $i++) {
		$hash = (leftShift32($hash, 5) + $hash) + ord(substr($value, $i));
	}
	return $hash;
}

// Perform a 32bit left shift
function leftShift32($number, $steps) {
	// convert to binary (string)
	$binary = decbin($number);
	// left-pad with 0's if necessary
	$binary = str_pad($binary, 32, "0", STR_PAD_LEFT);
	// left shift manually
	$binary = $binary.str_repeat("0", $steps);
	// get the last 32 bits
	$binary = substr($binary, strlen($binary) - 32);
	// if it's a positive number return it
	// otherwise return the 2's complement
    return ($binary{0} == "0" ? bindec($binary) :
		-(pow(2, 31) - bindec(substr($binary, 1))));
}

if (rpHash($_POST['realPerson']) == $_POST['realPersonHash']) {
	...

Java

private String rpHash(String value) {
	int hash = 5381;
	value = value.toUpperCase();
	for(int i = 0; i < value.length(); i++) {
		hash = ((hash << 5) + hash) + value.charAt(i);
	}
	return String.valueOf(hash);
}

if (rpHash(request.getParameter("realPerson")).equals(
		request.getParameter("realPersonHash"))) {
	...

C#

private string rpHash(string value) {
	int hash = 5381;
	value = value.ToUpper();
	for (int i = 0; i < value.Length; i++) {
		hash = ((hash << 5) + hash) + value[i];
	}
	return hash.ToString();
}

if (rpHash(Request.Form["realPerson"]) == Request.Form["realPersonHash"]) {
	...

In the Wild

This tab highlights examples of this plugin in use "in the wild".

To add another example, please contact me (kbwood{at}iinet.com.au) and provide the plugin name, the URL of your site, its title, and a short description of its purpose and where/how the plugin is used.

Quick Reference

A full list of all possible settings is shown below. Note that not all would apply in all cases. For more detail see the documentation reference page.

$(selector).realperson({
	length: 6, // Number of characters to use
	includeNumbers: false, // True to use numbers as well as letters
	regenerate: 'Click to change', // Instruction text to regenerate
	hashName: '{n}Hash' // Name of the hash value field to compare with,
		// use {n} to substitute with the original field name
});

$.realperson.setDefaults(settings) // Change settings for all instances

$(selector).realperson('change', settings) // Change the instance settings

$(selector).realperson('destroy') // Remove the real person functionality

Usage

  1. Include the jQuery library in the head section of your page.
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
  2. Download and include the jQuery Real Person CSS and JavaScript in the head section of your page.
    <style type="text/css">@import "jquery.realperson.css";</style>
    <script type="text/javascript" src="jquery.realperson.js"></script>
    Alternately, you can use the packed version jquery.realperson.pack.js (5.4K vs 8.0K), or the minified version jquery.realperson.min.js (4.9K, 1.4K when zipped).
  3. Connect the real person functionality to your input fields.
    $(selector).realperson();
    You can include custom settings as part of this process.
    $(selector).realperson({length: 5});

For more detail see the documentation reference page. Or see a minimal page that you could use as a basis for your own investigations.

Comments

None as yet.

Contact Keith Wood at kbwood{at}iinet.com.au with comments or suggestions.

Change History

VersionDateChanges
1.0.131 Oct 2009
  • Fixed layout in IE
1.0.027 Jun 2009
  • Initial release

Valid HTML 4.01 Strict