CodeCodex @ whatisfound.com

CSS 'clip' property

Ever watched a movie where a secret agent spy is hacking into someone's computer, and they plug in their trusty Hacks-A-Lot™ spy gadget and slowly the password is cracked as several letters that are all rapidly changing begin to one-by-one lock into the correct character? If only hacking were that simple... But at least it can look that simple! You can use this effect to dazzle unsuspecting people into thinking you're more of a security risk than you really are.

Example

Type something in the text field on the left, and then press 'Decrypt' to watch it de-scramble here.

Explained

There are three functions that I use to achieve this effect.

getRandomLetter()

function getRandomLetter() { // *** The actual array has all 52 upper- and lower-case letters explicitly written in, // *** I am simply abbreviating here for convenience. var letters = ['a','b','c','d',...'W','X','Y','Z']; var num = Math.floor(Math.random() * 10000) % 52; return letters[num]; }

getRandomLetter() does pretty much what it sounds like: returns a random letter from the set of uppercase and lowercase characters of the Roman alphabet. This is called several times at each step of "decryption" to create the ever-changing, ever- diminishing string of garbage after the partially revealed word.

Math.random() is a means of (big surprise) generating "random" numbers. Out of the box, the method returns a value between 0 and 1 with 16 digits of precision (16 decimal places). Rarely do I find that it is useful in this form, so I use the implementation above to transform it into a value a little more manageable. Here's what happening in this case:

  1. Math.random() - Get a random number (between 0 and 1).
  2. times 10000 - Move the decimal five places to the right. This number is arbitrary, but serves to ensure that I take the modulus of a larger pool of values. (i.e. if I only multiplied by, say, 10, I could never get values out of the range 0 - 9)
  3. Math.floor(...) - Rounds the supplied argument down to the nearest integer.
  4. mod 52 - Restrict the values to the range of 0 - 51. This is what changes from case to case, depending on what range of values I need.

Random is in quotes above because it isn't really random, but rather based off of the computer's clock when the method is invoked. This is significant in statistical or scientific arenas, but for picking an array index value out of a hat, it is perfectly suitable.

printDecryptionText(targetElement, plaintext, visibleLength)

function printDecryptionText(target, message, showlen) { if(showlen < message.length) { var string = message.substring(0,showlen); while(string.length != message.length) { string += getRandomLetter(); } target.innerHTML = string; } else { target.innerHTML = message; } }

This function accepts three arguments:

The function checks to see if the shown length of the string (showlen) is less than the full length of message, and if it is, the first X letters (X = showlen) of message are put into a string, and then random characters are added to it through calls to getRandomLetter() until that string is the same length as message.

If you called this method as printDecryptionText(div, "pantaloons", "4") (pretend 'div' is a variable already holding a <div> element), the phrase 'pant******' would become the contents of div, where ****** are all random characters.

decrypt(containingElement)

function decrypt(example) { var input = example.getElementsByTagName('input')[0]; var ctr = 0; var int = setInterval(function () { ctr++; },250); var int2 = setInterval(function () { printDecryptionText(input.nextSibling.nextSibling,input.value,ctr); if(ctr >= input.value.length) { clearInterval(int); clearInterval(int2); } },50); }

This is where the magic happens. decrypt() is really just two interval events. (Read more on setInterval and setTimeout.)

The second interval event calls printDecryptionText() every 5 hundredths of a second, while the first increments a counter used in that method call every quarter of a second. The counter sets showlen, which controls how many real characters are revealed of the original input message. The net effect is what you see at the top of a page: a garbled message that is replaced by another garbled message once every 1/20 of a second, and every 1/4 of a second, the message gets less garbled by one character.

Exposed

I'm currently compiling fun and useful methods such as this one into a library for public use, so check back soon if you want to use this function on your own page, but haven't the time to write it on your own.

Last updated: November 7th, 2009