- Overview
- Documents
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.
Usage
-
Include the jQuery library in the head section of your page.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
-
Download and include the jQuery Real Person CSS and JavaScript in the head section of your page.
<link rel="stylesheet" type="text/css" href="css/jquery.realperson.css"> <script type="text/javascript" src="js/jquery.realperson.js"></script>
Alternately, you can use the minimised version jquery.realperson.min.js (5.8K vs 10.1K, 1.7K when zipped). -
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});
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"]) { ...
Cold Fusion
Thanks to Emil Gudmundsson.
<cffunction name="rpHash" access="public" returntype="string" output="false"> <cfargument name="capText" type="string" required="true" /> <cfset var theHash = 5381 /> <cfset var theValue = UCase(ARGUMENTS.capText) /> <cfloop from="1" to="#Len(Trim(theValue))#" index="i"> <cfset theHash = (bitSHLN(theHash,5) + theHash) + Asc(Mid(theValue,i,1)) /> </cfloop> <cfreturn theHash /> </cffunction> <cfif rpHash(FORM.realPerson) EQ FORM.realPersonHash> ... </cfif>
Rails
Thanks to S. Muellner.
class FormController < BaseController # POST /form # POST /form.json def create realPerson = params[:realPerson] realPersonHash = params[:realPersonHash] if !realPerson.nil? && !realPersonHash.nil? && Integer(rpHash(realPerson)) == Integer(realPersonHash) # Accepted else # Rejected end end private def rpHash (defaultReal) hash = 5381 if !defaultReal.nil? defaultReal.upcase! defaultReal.length.times{ |i| hash = ((shift_32 hash, 5) + hash) + defaultReal[i].ord } end return hash end def shift_32 x, shift_amount shift_amount &= 0x1F x <<= shift_amount x &= 0xFFFFFFFF if (x & (1<<31)).zero? x else x - 2**32 end end end
Instance Settings
Customise each targetted input field with the settings below (all are optional):
$(selector).realperson({length: 4});
Name | Type | Default | Comments |
---|---|---|---|
length | number | 6 | The number of characters to be entered. |
includeNumbers | boolean | false | Set to true to include the digits 0 to 9 in the characters used to generate the challenge string. Otherwise only the alphabetic characters are used. |
regenerate | string | 'Click to change' | The text to display to inform the user that they may click on the challenge to generate a new value - in case they cannot easily read the original value. |
hashName | string | '{n}Hash' | The field name to use for the hash value that corresponds to the challenge text. Use '(n}' within the setting to substitute the name of the original input field. |
Functions
Signature | Returns | Comments |
---|---|---|
$.realperson.setDefaults(settings) | RealPerson object | Update the default instance settings to use with all real person instances. |
$(selector).realperson('option', options) | jQuery object |
Update the settings for the real person instance(s) attached to the given input(s). options (object) the collection of new settings. $(selector).realperson('option', {length: 8, includeNumbers: false}); Since 1.1.0 - previously you used the 'change' command. |
$(selector).realperson('option', name, value) | jQuery object |
Update a particular setting for the real person instance(s) attached to the given input(s). name (string) the name of the setting to change; value (any) the new value of that setting. $(selector).realperson('option', 'length', 8); Since 1.1.0. |
$(selector).realperson('option', name) | object or any |
Retrieve one or all of the current settings for the first real person instance attached to the given input(s). name (string, optional) the name of the setting to retrieve; omit for all settings. var settings = $(selector).realperson('option'); var length = $(selector).realperson('option', 'length'); Since 1.1.0. |
$(selector).realperson('enable') | jQuery object |
Enable the real person functionality for the given input(s). Since 1.1.0. |
$(selector).realperson('disable') | jQuery object |
Disable the real person functionality for the given input(s). Since 1.1.0. |
$(selector).realperson('destroy') | jQuery object | Remove the real person functionality from the given input(s). |