Doug Bryant

Tech thoughts and notes

Obfuscated Mailto - Ruby One Liner

I have always been annoyed at having to write email addresses online such as codefoo at bar dot com/code. Damn the spambots!

I recently ran across this technique for obfuscating email addresses on web pages so that it appears normal to the user, but not something which could be easily parsed by a spambot.

You convert the link text and href to html characters.

becomes (added line breaks for readability)

 Just a little bit more cryptic.

The core method for converting a string to an html character string is just a one line ruby method, of course.


def string_to_htmlc(s)
   s.strip.unpack(“C*”).map{|ch| “#” + ch.to_s + “;” }.to_s
end


A couple of things are going on here.

codes.strip.unpack(“C*)/code We first remove any leading or trailing whitespace with the strip method. The unpack method on string is used for decoding a string (possibly with binary data in it) into an array.  The argument code”C*"/code is an instruction that the next 0 to many characters should be turned into an unsigned integer, i.e. the number which represents the the ascii character.

We now need to convert our array of integers into the html code for each character.  The html code for a character is simply the ascii integer value for that character preceded by code#/code and ending with a code;/code.  The ruby map mehtod takes care of this for us.  Array#map invokes the block for each element in the array.

Finally we convert the array back into a string with the code.to_s/code for our html pleasure.  The code.to_s/code method on array is the same as calling codearray.join/code

All you have to do now is just put some code in your rails helper module to output a full href.


module MyHelper
def to_html_email(address)
email = string_to_htmlc(address)
“a href=\”#{string_to_htmlc(‘mailto:’)}#{email}\“#{email}/a”
end

def string_to_htmlc(s)
s.strip.unpack(“C*”).map{|ch| “#” + ch.to_s + “;” }.to_s
end

end


Now it should be safe to display an email address on a webpage.