在 PHP 中屏蔽信用卡号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13413886/
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
Mask credit card number in PHP
提问by fawad
I have credit card number which I want to mask as below:
我有信用卡号,我想屏蔽如下:
$cc = 1234123412341234
echo cc_masking($cc)
1234XXXXXXXX1234
function cc_masking($number) {.....}
Please suggest the regular expression for this.
请为此建议正则表达式。
回答by h2ooooooo
This should work using substr:
这应该使用substr:
function ccMasking($number, $maskingCharacter = 'X') {
return substr($number, 0, 4) . str_repeat($maskingCharacter, strlen($number) - 8) . substr($number, -4);
}
回答by Baba
You can use substr_replace
您可以使用 substr_replace
$var = '1234123412341234';
$var = substr_replace($var, str_repeat("X", 8), 4, 8);
echo $var;
Output
输出
1234XXXXXXXX1234
回答by Saddam Abu Ghaida
<?php
echo 'XXXX-XXXX-XXXX-'.substr($cc,-4);
?>
回答by Pachico
Assuming that:
假如说:
- Credit card numbers might be contained in a bigger string containing more content
- All major credit cards are sum-checked using the Luhn algorithm https://en.wikipedia.org/wiki/Luhn_algorithm
- 信用卡号可能包含在包含更多内容的更大字符串中
- 所有主要信用卡都使用 Luhn 算法进行总和检查https://en.wikipedia.org/wiki/Luhn_algorithm
This is what I do:
这就是我所做的:
- I detect, via regex, if a string contains a chain of digits, separated or not by spaces and hyphens.
- For every match, I strip it from non-numeric values and check if is a valid Luhn.
- Replace the part I want, for every match, with replacement characters (usually "*").
- 我通过正则表达式检测字符串是否包含一串数字,是否由空格和连字符分隔。
- 对于每个匹配项,我将其从非数字值中剥离并检查是否是有效的 Luhn。
- 对于每个匹配项,用替换字符(通常是“*”)替换我想要的部分。
The code is this:
代码是这样的:
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;
}
You will see a call to $this->_util_luhn->isLuhn, which is a function that does this:
您将看到对 $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));
}
It is how I implemented it in https://github.com/pachico/magoo/. Hope you find it useful.
这就是我在https://github.com/pachico/magoo/ 中实现它的方式。希望你觉得它有用。
回答by Andron
My 5 cents.
我的5美分。
Examples:
371449635398431 => XXX-XXXX-XXXX-8431
4111111111111111 => XXXX-XXXX-XXXX-1111
例如:
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;
}
回答by Alejandro Salamanca Mazuelo
With regular expression
使用正则表达式
function cc_masking( $number, $maskChar = 'X' ) {
return preg_replace(
'/^(....).*(....)$/',
'' . str_repeat( $maskChar, strlen( $number ) - 8) . '',
$number );
}
You keep the first four characters (and the last four), replacing the others with X.
您保留前四个字符(和最后四个),用 X 替换其他字符。
回答by romainberger
No need for regular expression for this. Just take n numbers at the beginning, n numbers at the end then add the X in the middle to complete.
不需要正则表达式。只需在开头取 n 个数字,在结尾取 n 个数字,然后在中间添加 X 即可完成。
回答by donald123
Not the elegant way but it works
不是优雅的方式,但它有效
<?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);
?>
回答by Khoi Pro
If you wish to show only last 4 digits, here is a dynamic way. Works with both credit cards, ACH numbers or anything:
如果您只想显示最后 4 位数字,这是一种动态方式。适用于信用卡、ACH 号码或任何东西:
https://gist.github.com/khoipro/815ea292e2e87e10771474dc2ef401ef
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;
回答by Gab
$accNum = "1234123412341234";
$accNum1 = substr($accNum,2,2);
$accNum1 = '**'.$accNum1;
$accNum2 = substr($accNum,6,100);
$accNum2 = '**'.$accNum2;
$accNum = $accNum1.$accNum2;
echo $accNum;

