【问题标题】:Mask credit card number in PHP在 PHP 中屏蔽信用卡号
【发布时间】:2023-03-13 05:41:01
【问题描述】:

我有信用卡号,我想掩蔽如下:

$cc = 1234123412341234

echo cc_masking($cc)

1234XXXXXXXX1234

function cc_masking($number) {.....}

请为此建议正则表达式。

【问题讨论】:

  • Fawad,请注意,Stack Overflow 不鼓励此类问题。绝大多数读者都喜欢看到实际已经尝试过的问题,或者至少是已经进行了大量研究工作的问题。

标签: php


【解决方案1】:

这应该可以使用 substr:

function ccMasking($number, $maskingCharacter = 'X') {
    return substr($number, 0, 4) . str_repeat($maskingCharacter, strlen($number) - 8) . substr($number, -4);
}

【讨论】:

  • 但是美国运通卡有 15 位数字。那我该怎么办?
  • @fawad 新代码应该可以工作 - 它将采用前 4 个数字,然后输入 X 以匹配字符串的长度 - 8,然后添加最后 4 个数字。
【解决方案2】:

您可以使用substr_replace

$var = '1234123412341234';
$var = substr_replace($var, str_repeat("X", 8), 4, 8);
echo $var;

输出

1234XXXXXXXX1234

【讨论】:

  • 非常简单好用
【解决方案3】:
<?php
echo 'XXXX-XXXX-XXXX-'.substr($cc,-4);
?>

【讨论】:

  • 好点,显示最后四位数字更加标准(尽管我认为应该在 X 中处理 15 位字符)。
  • 简单。太棒了
【解决方案4】:

我的 5 美分。

示例:
371449635398431 => XXX-XXXX-XXXX-8431
4111111111111111 => XXXX-XXXX-XXXX-1111

public function maskCreditCardNumber($cc, $maskFrom = 0, $maskTo = 4, $maskChar = 'X', $maskSpacer = '-')
{
    // Clean out
    $cc       = str_replace(array('-', ' '), '', $cc);
    $ccLength = strlen($cc);

    // Mask CC number
    if (empty($maskFrom) && $maskTo == $ccLength) {
        $cc = str_repeat($maskChar, $ccLength);
    } else {
        $cc = substr($cc, 0, $maskFrom) . str_repeat($maskChar, $ccLength - $maskFrom - $maskTo) . substr($cc, -1 * $maskTo);
    }

    // Format
    if ($ccLength > 4) {
        $newCreditCard = substr($cc, -4);
        for ($i = $ccLength - 5; $i >= 0; $i--) {
            // If on the fourth character add the mask char
            if ((($i + 1) - $ccLength) % 4 == 0) {
                $newCreditCard = $maskSpacer . $newCreditCard;
            }

            // Add the current character to the new credit card
            $newCreditCard = $cc[$i] . $newCreditCard;
        }
    } else {
        $newCreditCard = $cc;
    }

    return $newCreditCard;
}

【讨论】:

  • 您好,感谢您的功能,如果只有四位数字,如 1234 => xxxx 无效,请检查一次并更新
  • 主要思想是掩盖信用卡号。抄送号码的长度不能少于 12 个字符 - 检查here。在您的情况下,您可以致电...-&gt;maskCreditCardNumber('1234', 1, 1),结果将是1XX4
  • 您好,感谢您的回复,但这里我希望所有四位数字都应该是掩码 XXXX,因为它只有四位数字
  • 好的,更新了代码。您可以将其称为...-&gt;maskCreditCardNumber('1234', 0, 4),您将获得预期的结果。第三个参数可以是strlen($str)
【解决方案5】:

假设:

这就是我的工作:

  • 我通过正则表达式检测字符串是否包含由空格和连字符分隔的数字链。
  • 对于每场比赛,我将其从非数字值中剔除并检查是否是有效的 Luhn。
  • 用替换字符(通常是“*”)替换我想要的部分,每次匹配。

代码是这样的:

public function mask($string)
{
    $regex = '/(?:\d[ \t-]*?){13,19}/m';

    $matches = [];

    preg_match_all($regex, $string, $matches);

    // No credit card found
    if (!isset($matches[0]) || empty($matches[0]))
    {
        return $string;
    }

    foreach ($matches as $match_group)
    {
        foreach ($match_group as $match)
        {
            $stripped_match = preg_replace('/[^\d]/', '', $match);

            // Is it a valid Luhn one?
            if (false === $this->_util_luhn->isLuhn($stripped_match))
            {
                continue;
            }

            $card_length = strlen($stripped_match);
            $replacement = str_pad('', $card_length - 4, $this->_replacement) . substr($stripped_match, -4);

            // If so, replace the match
            $string = str_replace($match, $replacement, $string);
        }
    }

    return $string;
}

您将看到对 $this->_util_luhn->isLuhn 的调用,这是一个执行此操作的函数:

public function isLuhn($input)
{

    if (!is_numeric($input))
    {
        return false;
    }

    $numeric_string = (string) preg_replace('/\D/', '', $input);

    $sum = 0;

    $numDigits = strlen($numeric_string) - 1;

    $parity = $numDigits % 2;

    for ($i = $numDigits; $i >= 0; $i--)
    {
        $digit = substr($numeric_string, $i, 1);

        if (!$parity == ($i % 2))
        {
            $digit <<= 1;
        }

        $digit = ($digit > 9)
            ? ($digit - 9)
            : $digit;

        $sum += $digit;
    }

    return (0 == ($sum % 10));
}

这就是我在https://github.com/pachico/magoo/ 中实现它的方式。 希望对您有用。

【讨论】:

    【解决方案6】:

    带正则表达式

    function cc_masking( $number, $maskChar = 'X' ) {
        return preg_replace(
            '/^(....).*(....)$/',
            '\1' . str_repeat( $maskChar, strlen( $number ) - 8) . '\2',
            $number );
    }
    

    您保留前四个字符(和后四个),用 X 替换其他字符。

    【讨论】:

      【解决方案7】:

      如果您希望只显示最后 4 位数字,这是一种动态方式。适用于信用卡、ACH 号码或任何东西:

      https://gist.github.com/khoipro/815ea292e2e87e10771474dc2ef401ef

          $variable = '123123123';
          $length = strlen($variable);
          $output = substr_replace($variable, str_repeat('X', $length - 4), 0, $length - 4);
          echo $output;
      

      【讨论】:

      • 我添加了这个答案,因为我正在寻找那个解决方案。希望它可以帮助别人!
      【解决方案8】:

      不需要正则表达式。只需在开头取n个数字,在结尾取n个数字,然后在中间加上X即可完成。

      【讨论】:

        【解决方案9】:

        不是优雅的方式,但它有效

        <?php
             $cc = "1234123412341234";
             function cc_masking($number) {
             $int_first = 4;
             $int_last = 4;
             $chars = strlen($number);
             $repeater = "x";
             $repeates = $chars-$int_first-$int_last;
             // echo "<p>Org: $number</p>";
             $mask = substr($number,0,4).str_repeat($repeater,$repeates).substr($cc,-4);
             // echo "<p>Mask: $mask";
                 return $mask;
              }
             echo cc_masking($cc);
          ?>
        

        【讨论】:

          【解决方案10】:

          我正在寻找一些类似的代码。所以我找到了下面的代码。希望能帮到你。

          function mask($val, $mask)
          {
              $maskared = '';
          
              $k = 0;
          
              for ($i = 0; $i <= strlen($mask) - 1; $i++) {
                  if ($mask[$i] == '#') {
                      if (isset($val[$k]))
                          $maskared .= $val[$k++];
                  } else {
                      if (isset($mask[$i]))
                          $maskared .= $mask[$i];
                  }
              }
          
              return $maskared;
          }
          

          示例:

          echo mask(11111111111, "###.###.###-##"); // 111.111.111-11
          echo mask(11111111111, "#####-###"); // 111111-111
          echo mask(11111111111, anything); // 111111-111
          

          【讨论】:

            【解决方案11】:
            str_pad(substr($value,-4),strlen($value), "X", STR_PAD_LEFT); //output: XXXXXXXXXXXX9494
            

            【讨论】:

              【解决方案12】:
              $accNum = "1234123412341234";
              
              $accNum1 = substr($accNum,2,2);
              
              $accNum1 = '**'.$accNum1;
              
              $accNum2 = substr($accNum,6,100);
              
              $accNum2 = '**'.$accNum2;
              
              $accNum = $accNum1.$accNum2;
              
              echo $accNum;
              

              【讨论】:

              • 这导致**34**3412341234,与问题中的掩码不匹配。
              猜你喜欢
              • 1970-01-01
              • 2011-11-20
              • 2011-11-11
              • 2013-12-25
              • 1970-01-01
              • 1970-01-01
              • 2018-08-13
              • 2012-02-22
              相关资源
              最近更新 更多