在 PHP 中部分隐藏电子邮件地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20545301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:16:25  来源:igfitidea点击:

Partially hide email address in PHP

php

提问by Bluemagica

I am building a simple friend/buddy system, and when someone tries to search for new friends, I want to show partially hidden email addresses, so as to give an idea about who the user might be, without revealing the actual details.

我正在构建一个简单的朋友/好友系统,当有人尝试搜索新朋友时,我想显示部分隐藏的电子邮件地址,以便在不透露实际细节的情况下了解用户可能是谁。

So I want [email protected]to become abcdl******@hotmail.com.

所以我想[email protected]成为abcdl******@hotmail.com.

As a test I wrote:

作为测试,我写道:

<?php
$email = "[email protected]";

$em = explode("@",$email);
$name = $em[0];
$len = strlen($name);
$showLen = floor($len/2);
$str_arr = str_split($name);
for($ii=$showLen;$ii<$len;$ii++){
    $str_arr[$ii] = '*';
}
$em[0] = implode('',$str_arr); 
$new_name = implode('@',$em);
echo $new_name;

This works, but I was wondering if there was any easier/shorter way of applying the same logic? Like a regex maybe?

这有效,但我想知道是否有任何更简单/更短的方法来应用相同的逻辑?也许像正则表达式?

回答by msturdy

here's something quick:

这里有一些快速的东西:

function obfuscate_email($email)
{
    $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);   
}

// to see in action:
$emails = ['"Abc\@def"@iana.org', '[email protected]'];

foreach ($emails as $email) 
{
    echo obfuscate_email($email) . "\n";
}

echoes:

回声:

"Abc\*****@iana.org
abcdl*****@hotmail.com

uses substr()and str_repeat()

使用substr()str_repeat()

回答by Hein Andre Gr?nnestad

Here's my alternate solution for this.

这是我对此的替代解决方案。

I wouldn't use the exact number of mask characters to match the original length of the email, but rather use a fixed length mask for privacy reasons. I would also set the maximum allowed characters to show as well as never show more than half of the email. I would also mask all emails less than a minimum length.

我不会使用确切数量的掩码字符来匹配电子邮件的原始长度,而是出于隐私原因使用固定长度的掩码。我还会设置允许显示的最大字符数,以及从不显示超过一半的电子邮件。我还会屏蔽所有小于最小长度的电子邮件。

With those rules in mind, here's my function with optional parameters:

考虑到这些规则,这是我的带有可选参数的函数:

function maskEmail($email, $minLength = 3, $maxLength = 10, $mask = "***") {
    $atPos = strrpos($email, "@");
    $name = substr($email, 0, $atPos);
    $len = strlen($name);
    $domain = substr($email, $atPos);

    if (($len / 2) < $maxLength) $maxLength = ($len / 2);

    $shortenedEmail = (($len > $minLength) ? substr($name, 0, $maxLength) : "");
    return  "{$shortenedEmail}{$mask}{$domain}";
}

Tests:

测试:

$email = "";
$tests = [];
for ($i=0; $i < 22; $i++) {
    $email .= chr(97 + $i);

    $tests[] = $email . " -> " . maskEmail("{$email}@example.com");
}
print_r($tests);

Results:

结果:

Array
(
    [0] => a -> ***@example.com
    [1] => ab -> ***@example.com
    [2] => abc -> ***@example.com
    [3] => abcd -> ab***@example.com
    [4] => abcde -> ab***@example.com
    [5] => abcdef -> abc***@example.com
    [6] => abcdefg -> abc***@example.com
    [7] => abcdefgh -> abcd***@example.com
    [8] => abcdefghi -> abcd***@example.com
    [9] => abcdefghij -> abcde***@example.com
    [10] => abcdefghijk -> abcde***@example.com
    [11] => abcdefghijkl -> abcdef***@example.com
    [12] => abcdefghijklm -> abcdef***@example.com
    [13] => abcdefghijklmn -> abcdefg***@example.com
    [14] => abcdefghijklmno -> abcdefg***@example.com
    [15] => abcdefghijklmnop -> abcdefgh***@example.com
    [16] => abcdefghijklmnopq -> abcdefgh***@example.com
    [17] => abcdefghijklmnopqr -> abcdefghi***@example.com
    [18] => abcdefghijklmnopqrs -> abcdefghi***@example.com
    [19] => abcdefghijklmnopqrst -> abcdefghij***@example.com
    [20] => abcdefghijklmnopqrstu -> abcdefghij***@example.com
    [21] => abcdefghijklmnopqrstuv -> abcdefghij***@example.com
)

回答by Szymon Marczak

Maybe this is not what you want, but I would go for this:

也许这不是你想要的,但我会这样做:

<?php

    /*

    Here's the logic:

    We want to show X numbers.
    If length of STR is less than X, hide all.
    Else replace the rest with *.

    */

function mask($str, $first, $last) {
    $len = strlen($str);
    $toShow = $first + $last;
    return substr($str, 0, $len <= $toShow ? 0 : $first).str_repeat("*", $len - ($len <= $toShow ? 0 : $toShow)).substr($str, $len - $last, $len <= $toShow ? 0 : $last);
}

function mask_email($email) {
    $mail_parts = explode("@", $email);
    $domain_parts = explode('.', $mail_parts[1]);

    $mail_parts[0] = mask($mail_parts[0], 2, 1); // show first 2 letters and last 1 letter
    $domain_parts[0] = mask($domain_parts[0], 2, 1); // same here
    $mail_parts[1] = implode('.', $domain_parts);

    return implode("@", $mail_parts);
}

$emails = array(
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]'
);

foreach ($emails as $email){
    echo '<b>'.$email.'</b><br>'.mask_email($email).'<br><hr>';
}

Result:

结果:

[email protected]
*@*.com

[email protected]
**@**.com

[email protected]
***@***.com

[email protected]
ab*d@aa*a.com

[email protected]
ab**e@aa**a.com

[email protected]
ab***f@aa***a.com

[email protected]
ab****g@aa****a.com

[email protected]
ab*****h@aa*****a.com

[email protected]
ab******i@aa******a.com

回答by Hani

I created a function can help someone

我创建了一个功能可以帮助某人

    function hideEmail($email)
{
    $mail_parts = explode("@", $email);
    $length = strlen($mail_parts[0]);
    $show = floor($length/2);
    $hide = $length - $show;
    $replace = str_repeat("*", $hide);

    return substr_replace ( $mail_parts[0] , $replace , $show, $hide ) . "@" . substr_replace($mail_parts[1], "**", 0, 2);
}

hideEmail("[email protected]"); // output: na**@**ample.com
hideEmail("[email protected]"); // output: some*****@**ample.com

You can customize as you want .. something like this (if length is 4 or less display only the first)

您可以根据需要自定义 .. 类似这样的东西(如果长度为 4 或更少,则只显示第一个)

    function hideEmail($email) {
    $mail_parts = explode("@", $email);
    $length = strlen($mail_parts[0]);

    if($length <= 4 & $length > 1)
    {
        $show = 1;
        }else{
        $show = floor($length/2);       
    }

    $hide = $length - $show;
    $replace = str_repeat("*", $hide);

    return substr_replace ( $mail_parts[0] , $replace , $show, $hide ) . "@" . substr_replace($mail_parts[1], "**", 0, 2);  
}

hideEmail("[email protected]"); // output: n***@**ample.com
hideEmail("[email protected]"); // output: some*****@**ample.com

回答by niki

I'm using this:

我正在使用这个:

 function secret_mail($email)
{

$prop=2;
    $domain = substr(strrchr($email, "@"), 1);
    $mailname=str_replace($domain,'',$email);
    $name_l=strlen($mailname);
    $domain_l=strlen($domain);
        for($i=0;$i<=$name_l/$prop-1;$i++)
        {
        $start.='x';
        }

        for($i=0;$i<=$domain_l/$prop-1;$i++)
        {
        $end.='x';
        }

    return substr_replace($mailname, $start, 2, $name_l/$prop).substr_replace($domain, $end, 2, $domain_l/$prop);
}

Will output something like: cyxxxxxone@gmxxxxcom

将输出类似:cyxxxxxone@gmxxxxcom

回答by Igoooor

For instance :

例如 :

substr($email, 0, 3).'****'.substr($email, strpos($email, "@"));

Which will give you something like:

这会给你类似的东西:

abc****@hotmail.com

abc****@hotmail.com

回答by Michael Nguyen

I m using femich answer above and tweak it a bit for my

我正在使用上面的 femich 答案并为我的

function mask_email($email, $char_shown_front = 1, $char_shown_back = 1)
{
    $mail_parts = explode('@', $email);
    $username = $mail_parts[0];
    $len = strlen($username);

    if ($len < $char_shown_front or $len < $char_shown_back) {
        return implode('@', $mail_parts);
    }

    //Logic: show asterisk in middle, but also show the last character before @
    $mail_parts[0] = substr($username, 0, $char_shown_front)
        . str_repeat('*', $len - $char_shown_front - $char_shown_back)
        . substr($username, $len - $char_shown_back, $char_shown_back);

    return implode('@', $mail_parts);
}

[email protected] -> t*****[email protected]

[email protected] -> t*****[email protected]

you can pass in the number of character to show in the front and in the back

您可以传入要显示在前面和后面的字符数

回答by fedmich

Sometimes its good to show the last charactertoo.

有时显示最后一个字符也很好。

[email protected] becomes A*****[email protected]

[email protected] 变为 A*****[email protected]

I will suggest you keep things simple. Maybe something like this is simple enough https://github.com/fedmich/PHP_Codes/blob/master/mask_email.php

我会建议你保持简单。也许这样的事情很简单 https://github.com/fedmich/PHP_Codes/blob/master/mask_email.php

Masks an email to show first 3 characters and then the last character before the @ sign

屏蔽电子邮件以显示前 3 个字符,然后显示 @ 符号前的最后一个字符

function mask_email( $email ) {
    /*
    Author: Fed
    Simple way of masking emails
    */

    $char_shown = 3;

    $mail_parts = explode("@", $email);
    $username = $mail_parts[0];
    $len = strlen( $username );

    if( $len <= $char_shown ){
        return implode("@", $mail_parts );  
    }

    //Logic: show asterisk in middle, but also show the last character before @
    $mail_parts[0] = substr( $username, 0 , $char_shown )
        . str_repeat("*", $len - $char_shown - 1 )
        . substr( $username, $len - $char_shown + 2 , 1  )
        ;

    return implode("@", $mail_parts );
}

回答by Daud khan

I have a function

我有一个功能

function hide_email($email){
$final_str = '';
$string = explode('@', $email);
$leftlength = strlen($string[0]);
$string2 = explode('.', $string[1]);
$string2len = strlen($string2[0]);
$leftlength_new = $leftlength-1;
$first_letter = substr($string[0], 0,1);
$stars = '';
$stars2 = '';
for ($i=0; $i < $leftlength_new; $i++) { 
    $stars .= '*';
}
for ($i=0; $i < $string2len; $i++) { 
    $stars2 .= '*';
}
$stars;
return $final_str .= $first_letter.$stars.'@'.$stars2.'.'.$string2[1];

}

}

echo hide_email('[email protected]');

echo hide_email('[email protected]');

回答by Waqas

There was an issue in case if there would be 1 character before @. I have fixed in below function.

如果@ 之前有1 个字符,则会出现问题。我已经修复了以下功能。

function obfuscate_email($email)

{  

   $em   = explode("@",$email);
   if(strlen($em[0])==1){
       return   '*'.'@'.$em[1];
   }
   $name = implode(array_slice($em, 0, count($em)-1), '@');
   $len  = floor(strlen($name)/2);
   return substr($name,0, $len) . str_repeat('*', $len) . "@" . end($em);

}