Last updated 20 June 2009. Created on 13 June 2007.
Edited by bryan kennedy, sradomski. Log in to edit this page.

This is a good starting point for some kind of obfuscation technique, but on its own it may no longer be effective because of the evolving techniques used by spam harvesters.

This snippet will replace all email addresses in a href="mailto:" by its hexadecimal representation. Thus making email harvesting for spammers harder to do while still retaining the functionality for the user to click on the link and send an email through an email-client.

It is just an implementation of hook_filter, see the filter_example.module to turn this snippet into a valid module.

function obfuscate_email_filter($op, $delta = 0, $format = -1, $text = '') { 
  if ($op == 'list') { 
    return array( 
      0 => t('Obfuscate email addresses'));

  switch ($delta) { 
    case 0: 
      switch ($op) { 
        case 'description': 
          return t('Obfuscates mailto: email-addresses.'); 

        case 'prepare': 
          return $text; 

        case 'process':
          $pos = 0;
          $oldpos = 0;
          $pat = "/[a-zA-Z]+[a-zA-Z0-9]*[\.|\-|_]?[a-zA-Z0-9]+@([a-zA-Z]+[a-zA-Z0-9]*[\.|\-|_]?[a-zA-Z]+[a-zA-Z0-9]*[a-zA-Z0-9]+){1,4}\.[a-zA-Z]{2,4}/";
            # to improve performance, match 'href=mailto:' with static string matching
            while($pos = strpos($text, 'href="mailto:', $pos+1)) {
              $matches = array();
              # a few characters after $pos, the email address begins
              # preg_match stops after the first match, so this should be fast enough
              preg_match($pat, $text, $matches, PREG_OFFSET_CAPTURE, $pos);
              $len = strlen($matches[0][0]);
              $pos = $matches[0][1];
              $temp .= substr($text, $oldpos, $pos-$oldpos);
              # replace the email address by its hex values
              for ($i = 0; $i < $len; $i++) {
                $temp .= "&#" . ord($matches[0][0][$i]);
              $oldpos = $pos+$len;
            $temp .= substr($text, $oldpos, strlen($text)-$oldpos);
            $text = $temp;
          return $text;

Feel free to criticise and improve the code. The regular expression in $pat is a modified version of a comment from There are still some cases where only parts of the email address are obfuscated.

One might want to obfuscate all occuring email addresses in $text, but this is good enough for me and I am hesitant to use preg_match_all or iterate with preg_match due to performance considerations. Though I have to admit that I did not run any benchmarks.

Looking for support? Visit the forums, or join #drupal-support in IRC.