As part of my ongoing online response to some great questions, I offer the following request by Colin Kuskie, webmaster for the Sunset Presbyterian Church:
Hi Dean,
My name is Colin Kuskie, and I’m Sunset Presbyterian Church’s
volunteer webmaster/hostmaster. I’m planning on moving our website,
www.sunsetpres.org, to a CMS, and I’d like to help secure staff
and member email addresses against spam by using your obfuscator
as a macro, but I couldn’t find anywhere to download the code from
your site.
Is it publicly available, and if so, could you please give me a
pointer as to how to find it?
Thank you,
Colin
p.s. Thank you very much for your online minstry. It’s one of
the things that convinced me to go to a CMS, and then to teach
myself CSS in order to implement it. I pray that God will you
your website to enable other churches to reach out with God’s
message to the world.
How can I say no to a request like that? So I emailed Colin back with the response “… Colin, stop it, my ego is already ‘well maximized’ enough!” … Actually, that’s not what I said, but I thought it might be fun to share a little opera singer humor with you. Go ahead, ask your minister of music about their well-optimized ego … but I digress …
Actually, my first response to Colin was “Macro? For what system?.” This wasn’t out of any suspicion, but more out of curiosity, and more out of concern that my original obfuscator hack wouldn’t integrate all that well as it was built into an online form generated using CGI.PM. Colin responded that he intends to integrate the code behind the Mean Dean Anti-Spam E-Mail Obfuscator(MDA-SE-MO) into a macro for a Perl-based content manglement system (CMS) named WebGUI. A robust system I’ve played with once or twice before, but don’t let my ease-of-use fool you. This is one CMS that requires you know Perl, paths and your site map before you go shooting your foot off of with it … but I digress …
CMS sorties aside, Colin’s question reminded me of this sage advice she’d offer whenever I’d leave the house: “make sure you have on clean underwear.” Not that it would help if the last thing I ever saw was an oncoming cement truck … but I digress …
So, if I’m going to put my code ‘out there,’ I had better tidy it up a bit, and put it into a easy to deploy, use and maintain Perl module. This way, he could use it for WebGUI, and I could use it for an upcoming MovableType plug-in … unless one of you kind souls comes up with it first … but I digress …
I also figured if I as going to put it ‘out there,’ I might as well add an option that might really, truly drive spammer’s nutzo … that is to render the hyperlink as inline javascript. Yes, I know 12% of all browsers have Javascript disabled, but then again, how many people using wGet or Curl are actually interested in sending me email? That said, it is for such reasons that I have in the past advocated including a form-based email solution on your church or charity website. All the more so if you’re going to use the inline javascript option on Obfuscator … but perhaps this tangent is better left as a topic for later discussion?
Anyway, below is the code for the new perl module behind the slightly improved online demonstration of the MDA-SE-MO:
package Obfuscator;
##############################################################
# Obfuscator (c) 2002-2003 #
# Dean Peters #
# http://www.healyourchurchwebsite.com/obfuscator/ #
# #
# use Obfuscator; #
# print “Problems? Questions? “. #
# OB_encode( “obfuscater\@healyourchurchwebsite.org”, #
# “drop me a line.”, #
# “Problem? Praise? Email Me”, true); #
# #
##############################################################
# This package obfuscates email #
##############################################################
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(OB_encode OB_validmail);
use vars qw($volumes $books $versions);
sub OB_encode {
my($email, $prompt, $title, $usejs) = @_;
# return if email doesn’t validate
return if( $email !~ /[\w\-\[\]<>\+]+(\@|\-at\-)[\w\-\[\]<>]+(\.|\-dot\-)[\w\-]+/i);
# mangle address — character at a time –except \@
$email =~ s/(:)([^\s])/$1 $2/;
$email =~ s/([a-zA-Z0-9:\s_\-.])/&OB_randlet($1)/eg;
my $at = &OB_randlet(“\@”);
my ($ename, $edomain) = split(/\@/, $email);
my $link = $ename.$at.$edomain;
# want address only? no problem.
return $link if !($prompt || $title);
# put a space between mailto: and the address (drives spammers crazy)
my($mailto) = &OB_ascape(“mailto:”).&OB_hexape(” “);
# build hyperlink based on use javascript argument (or not)
$link = $usejs ?
“javascript:var e1=’$edomain’,e2=’$mailto’, e3=’$ename’;var e0=e2+e3+’$at’+e1;(window.location?window.location.replace(e0):document.write(e0));” :
$mailto.$link;
# try to use a title, but when you can’t …
$prompt = &OB_ascape($prompt);
return qq~$prompt~ if !($title);
# got title?
$title = &OB_ascape($title);
return qq~$prompt~;
}
# http://ironbark.bendigo.latrobe.edu.au/subjects/bitwen/lectures/w08.d/l15.d/slide3.html
sub OB_validmail {
my($email) = @_;
return ( $email =~ /^([\w\-._]+\@[\w\-.]+)$/ );
}
# 2 randoms, 1st for hex vs ascii, then again for ascii vs plain
sub OB_randlet {
my($l) = @_;
my($r) = &OB_round(rand());
return sprintf(“%%%02x”,ord($l)) if $r;
$r = &OB_round(rand());
return sprintf(“&#%03d;”,ord($l)) if $r;
return $l;
}
# real numbers only
sub OB_round {
my($n) = @_;
return int($n + .5 * ($n <=> 0));
}
# ascii escape codes
sub OB_ascape {
my($s) = @_;
$s =~ s/([a-zA-Z0-9:\s\@_\-.])/uc sprintf(“&#%03d;”,ord($1))/eg;
return $s;
}
# hex it up a bit
sub OB_hexape {
my($s) = @_;
$s =~ s/([a-zA-Z0-9:\s\@_\-.])/uc sprintf(“%%%02x”,ord($1))/eg;
return $s;
}
1;
__END__
=head1 NAME
Obfuscator – mangles email addresses to fool dumb spambots
=head1 SYNOPSIS
use Obfuscator;
print OB_encode($email, $prompt, $title, $usejs) if OB_validmail($email);
$email – required string representing an email address, remember, in Perl
it’s my $email = “foo\@bar.com” … note the slash
$prompt – optional string of the prompt you want between the .. tags
$title – optional string that is used for title argument of tag
$usejs – renders obfuscated hyperlink as a javascript link
=head1 DESCRIPTION
Obfuscator randomly converts your entries into a combination of numeric and
hexadecimal encodings, as well as a salting of some non-converted characters
that will either hide your e-mail address from spambots and/or cause their
mailers to gag because they’re not expecting all three encoding in radom.
This program also obfuscates the prompts to give spambots less key words to
search, find and filche.
=head1 IMPROVEMENTS
* n/a
=head1 BUGS
* n/a
=head1 AUTHOR
Dean Peters
=head1 EXAMPLE
use Obfuscator;
my $email = “obfuscater\@healyourchurchwebsite.org”;
print “Problems? Questions? “.
OB_encode($email, “drop me a line.”,
“Problem? Praise? Email Me”, true)
if OB_validmail($email);
=head1 COPYRIGHT and LICENSE
Copyright (c) 2002-2003
Dean Peters
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The Software is not included in any commercial application or publication
without the expressed written permission of Dean Peters.
The Software is provided “as is”, without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall
the authors or copyright holders be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising
from, out of or in connection with the Software or the use or other
dealings in the Software.
=cut
Yes, this obfuscator isn’t nearly as dastardly as the very cool and very effective online offering from HiveWare (hat tip to Mark Pilgrim) … perhaps by putting the Obfuscator.pm code ‘out there’ … someone will come up with an elegant “<noscript>” solution. I’ve already got one person who’s keen on optimizing the regular expressions … Colin, thank you.