Friday, July 8, 2016

Obfuscate Your Email Address

I had a boss who once told me, "Your best attribute is also your worst attribute". In his example he cited that people who were good speakers were generally not good listeners. The Internet is no different.

Email is a wondrous thing. It saves time and money and makes it much easier to be/stay connected to everyone in your world. The downside is SPAM, it's rare to run into someone who's not getting more than they would like. The big email providers like Gmail, Yahoo, and Microsoft all do a pretty good job of keeping SPAM out of your mailbox. But things change some if you have a website.

One of the primary reasons to have a website is to make yourself available to the public. In today's world; that  includes email, which means you have 2 options. One is to have a contact page, which hides your email address but makes the sender feel a little disconnected. After all, they don't know where this email is going; it feels impersonal. The other is to just display your email address on your site. It's much more personal and gives someone a feeling that they have a more "direct" connection with you.

Regardless of which method you choose; both make you more susceptible to SPAM. I would like to discuss both of these issues with you, one at a time. This entry will cover the direct display of your email address. My next entry will talk about protecting yourself when using a contact form.

The largest drawback to displaying your email address on the Internet is the "bot". Bots are automated routines that constantly scour the Internet page by page. They read the code of each page line by line. Their purpose is to find the email address and add it to a list. Once you get on that list, the unwanted email will start.

The best method at this time is to "obfuscate" your email address from the "bots". The best method to do so at this time is to use ROT13 encryption. What is that? Here is the definition from the PHP manual:

"The ROT13 encoding simply shifts every letter by 13 places in the alphabet while leaving non-alpha characters untouched. Encoding and decoding are done by the same function, passing an encoded string as argument will return the original version."

So let's say your email address is:

me@someplace.com

You can make it look like

zr@fbzrcynpr.pbz

to a "bot".

The best way to accomplish this is to use a small piece of Javascript code to display your email as a clickable link on your page.

You can see (and use) a working example of what follows at my web site Hired Gun Coding.

The code that provides all the "magic" is below:

document.write("<n uers=\"znvygb:zr@fbzrcynpr.pbz\">zr@fbzrcynpr.pbz</n>.replace(/[a-zA-Z]/g, function(o){return String.fromCharCode((o<="Z"?90:122)>=(o=o.charCodeAt(0)+13)?o:o-26);}));

So what does all the above mean?

document.write()

is one of the most basic of Javascript functions, it displays whatever is put between the parentheses () on the screen.

<n uers=\"znvygb:zr@fbzrcynpr.pbz\">zlnqqerff@fbzrcynpr.pbz</n>

this is the address which has been encoded by moving the letter up by 13. If you count back the letters from "n" you will count back to the letter "a". So "<n" actually decodes to "<a" which is the beginning of the hyperlink tag. Which means "uers" is "href" and "znvygb" decodes to "mailto".

.replace()

is the Javascript function that does the decoding. The replace function has 2 parameters searchvalue and newvalue.

/[a-zA-Z]/g

this is the "searchvalue" parameter. [a-zA-Z] means replace the lowercase letters a-z or the upper case letters A-Z. It's enclosed between /  /g which means "global", or replace all occurrences found, not just the first one.

function(o)

This is the beginning of the "newvalue parameter and it is the function that actually decodes each individual letter.

String.fromCharCode()

is the Javascript function that turns the final character code (as calculated by the function) in the letter to display on the screen.

(o<="Z"?90:122)>=(o=o.charCodeAt(0)+13)?o:o-26

This is probably the most intimidating part of the code but is actually easily explained.

(o<="Z"?90:122)

This equation checks to see if the character passed is less than or equal to a capital Z. It uses the ? or a "ternary" operator. Mozilla defines the ternary operator this way:

"The conditional (ternary) operator is the only JavaScript operator that takes three operands. This operator is frequently used as a shortcut for the if statement."

Uppercase letters have a lower character code (ASCII number) than lowercase which is why you test for that first. If the letter is less than the capital Z it's ASCII code 90 is used, otherwise the code for a lowercase z 122 is used.

(o=o.charCodeAt(0)+13)?o:o-26

o.charCodeAt(0) + 13 takes the character (ASCII) code passed to it and adds 13. The final ternary operation ?o:o-26 makes the final adjustment. Because when encoded the character (ASCII) value was increased by 13 it will never equal what was originally passed, so the second operator 0-26 is used subtracting 26 which returns it back to its original character (ASCII) code.

What that means is this:

Let's say the lowercase m was encoded using ROT13, the character (ASCII) code for it is 109. ROT13 encoding adds 13 to the character (ASCII) code of 109; which is what makes it becomes a lower case z. A lowercase z has a character code of 122. So when decoded, by adding 13 to 122 you get a result of 135 which is NOT the letter m. Since by now we have added 13 to the original character (ASCII) code twice; subtracting 26 (from 135) returns it to it's original value of 109, the character (ASCII) code for a lowercase m.

Does your head hurt yet?

The only thing left is to encrypt the email address you want to put in. That is simple enough and can be done using PHP using the str_rot13 function.

$email = str_rot13("my@someplace.com");

To use it in a web page, it all goes together like this:

At the top of your page:

<?PHP

$email = str_rot13("my@someplace.com");

?>

Then in your HTML where you want the mail link to appear drop this code:

<script type="text/javascript">document.write("<n uers=\"<? echo $email; ?>\"><? echo $email; ?></n>.replace(/[a-zA-Z]/g, function(o){return String.fromCharCode((o<="Z"?90:122)>=(o=o.charCodeAt(0)+13)?o:o-26);}))</script>

That will display

me@someplace.com

It's hard to say how long this method will hold things off, but it's safe to say that it will be for quite some time. The people who code these "bots" are looking for the "low hanging fruit" of the Internet; those who don't do anything to protect their email address. What has done here would require a bit of extra code for them to find the address, which is not something they'll be willing to spend their time on.

No comments:

Post a Comment