Assuming that:
This is what I do:
- I find through regex if a string contains a whole string of numbers, separated or not by spaces or hyphens.
- For each match, I separate it from non-numeric values ββand check if it is a valid moon.
- Replace the part I want for each match, with replacement characters (usually "*").
The code looks like 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 performs the function:
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)); }
That is how I implemented it at https://github.com/pachico/magoo/ . I hope you find this helpful.
source share