寻找一个仅使用PHP的电子邮件地址混淆函数

11

是否有仅使用PHP的电子邮件地址混淆函数?在网络上找到的大多数函数都是JS和PHP的混合。


你是指需要填写验证码才能收到真正的电子邮件地址吗? ;) - Gung Foo
6个回答

18

以下是我使用的一些函数。

第一个函数使用HTML字符代码混淆电子邮件地址:

function getObfuscatedEmailAddress($email)
{
    $alwaysEncode = array('.', ':', '@');

    $result = '';

    // Encode string using oct and hex character codes
    for ($i = 0; $i < strlen($email); $i++) {
        // Encode 25% of characters including several that always should be encoded
        if (in_array($email[$i], $alwaysEncode) || mt_rand(1, 100) < 25) {
            if (mt_rand(0, 1)) {
                $result .= '&#' . ord($email[$i]) . ';';
            } else {
                $result .= '&#x' . dechex(ord($email[$i])) . ';';
            }
        } else {
            $result .= $email[$i];
        }
    }

    return $result;
}

例子:

echo getObfuscatedEmailAddress('firstname.last-name@example.com');
-->
firstn&#x61;m&#x65;&#x2e;la&#115;t-name&#x40;examp&#108;e&#46;&#x63;om

第二个将返回电子邮件地址同时进行了HTML和URL编码的链接:

function getObfuscatedEmailLink($email, $params = array())
{
    if (!is_array($params)) {
        $params = array();
    }

    // Tell search engines to ignore obfuscated uri
    if (!isset($params['rel'])) {
        $params['rel'] = 'nofollow';
    }

    $neverEncode = array('.', '@', '+'); // Don't encode those as not fully supported by IE & Chrome

    $urlEncodedEmail = '';
    for ($i = 0; $i < strlen($email); $i++) {
        // Encode 25% of characters
        if (!in_array($email[$i], $neverEncode) && mt_rand(1, 100) < 25) {
            $charCode = ord($email[$i]);
            $urlEncodedEmail .= '%';
            $urlEncodedEmail .= dechex(($charCode >> 4) & 0xF);
            $urlEncodedEmail .= dechex($charCode & 0xF);
        } else {
            $urlEncodedEmail .= $email[$i];
        }
    }

    $obfuscatedEmail = getObfuscatedEmailAddress($email);
    $obfuscatedEmailUrl = getObfuscatedEmailAddress('mailto:' . $urlEncodedEmail);

    $link = '<a href="' . $obfuscatedEmailUrl . '"';
    foreach ($params as $param => $value) {
        $link .= ' ' . $param . '="' . htmlspecialchars($value). '"';
    }
    $link .= '>' . $obfuscatedEmail . '</a>';

    return $link;
}

例子:

echo getObfuscatedEmailLink('firstname.last-name@example.com');
-->
<a href="mailt&#111;&#58;%66i&#37;72stna%&#54;d&#x65;&#46;&#37;6c&#x25;6&#x31;st&#x2d;name&#64;&#101;&#x78;&#x61;mple&#46;co&#109;" rel="nofollow">f&#x69;&#114;s&#x74;na&#109;e&#x2e;&#108;a&#x73;t-name&#64;e&#x78;ample&#46;co&#109;</a>

有趣的方法 +1。但它可能会有一些兼容性问题。 - Andreas Rehm
我还没有在Safari和移动浏览器上测试过。FF,IE,Chrome都可以。 - Alexei Tenitski
我喜欢这种方法。我会尝试一下,看看是否会收到垃圾邮件。 - GTCrais

14

我最喜欢的:

标记语言 + PHP

<span class="rev"><?php echo strrev($email); ?> </span>

CSS

.rev{
    direction: rtl;
    unicode-bidi: bidi-override;
}

Fiddle


1
太棒了!复制/粘贴电子邮件时这个怎么样? - A F
@AakilFernandes 看看这个 fiddle:(( - moonwave99
请注意,此方法过于简单且易于“反向工程”:if (email.indexOf('.') < email.indexOf('@')) email.reverse() - yckart
这个对于可访问性来说怎么样? - cwd
@AakilFernandes moc.elpmaxe@olleh - 所以它不是复制数据的合适解决方案。 - Andres SK

3

这里是一个带有类型提示的例子。

只需使用$this->obfuscateEmail($email);进行调用。

/**
 * @param string $email
 * @return string
 */
private function obfuscateEmail(string $email): string
{
    $em = explode("@", $email);
    $name = implode(array_slice($em, 0, count($em) - 1), '@');
    $len = floor(strlen($name) / 2);

    return substr($name, 0, $len) . str_repeat('*', $len) . "@" . end($em);
}

请注意,自 PHP 8 起,implode函数的参数应该被反转:$name = implode('@', array_slice($em, 0, count($em) - 1)); - v.nivuahc

2

这里列出的一些例子很棒,但是我选择了 WordPress 的 antispambot() 函数,下面是方便起见的代码:

function antispambot( $email_address, $hex_encoding = 0 ) {
    $email_no_spam_address = '';
    for ( $i = 0, $len = strlen( $email_address ); $i < $len; $i++ ) {
        $j = rand( 0, 1 + $hex_encoding );
        if ( 0 == $j ) {
            $email_no_spam_address .= '&#' . ord( $email_address[ $i ] ) . ';';
        } elseif ( 1 == $j ) {
            $email_no_spam_address .= $email_address[ $i ];
        } elseif ( 2 == $j ) {
            $email_no_spam_address .= '%' . zeroise( dechex( ord( $email_address[ $i ] ) ), 2 );
        }
    }

    return str_replace( '@', '&#64;', $email_no_spam_address );
}

function zeroise( $number, $threshold ) {
    return sprintf( '%0' . $threshold . 's', $number );
}

请参阅WordPress了解更多详细信息。


2

这里有一种更加紧凑的方法,不会导致https://validator.w3.org出现错误。

function obfuscate($email){
$encoded_email = '';
for ($a = 0,$b = strlen($email);$a < $b;$a++)
{
    $encoded_email .= '&#'.(mt_rand(0,1) == 0  ? 'x'.dechex(ord($email[$a])) : ord($email[$a])) . ';';
}
return $encoded_email;}

然后使用以下代码将其添加到页面中:

<a href="mailto:<?= obfuscate(CONTACT_EMAIL.'?subject=Hello!') ?>"><?= CONTACT_EMAIL ?></a>

0

如果主机前面有一个字符,这里提供一种替代方法:

/**
* @param string $email
* @return string
*/

private function obfuscateEmail($email)
{
    $em   = explode("@", $email);

    $name = implode(array_slice($em, 0, count($em)-1), '@');

    if(strlen($name)==1){
        return   '*'.'@'.end($em);
    }

    $len  = floor(strlen($name)/2);

    return substr($name,0, $len) . str_repeat('*', $len) . "@" . end($em);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接