E
E
evgabd2013-04-03 22:14:10
PHP
evgabd, 2013-04-03 22:14:10

How to mask a credit card number with a regular expression?

There is a POST request body:
cc_number=4111111111111111&amount=1500
To write to the log, you need to cast it to the form
cc_number=XXXXXXXXXXXXXXX&amount=1500
This can be done as follows:

$data = preg_replace(
    '/(?<=cc_number=)([^&]+)/e',
    'str_repeat("X", strlen("$1"))',
    $data);

But, since using the eval modifier is bad form and is deprecated in PHP 5.5, I rewrote the regular expression using preg_replace_callback :
$data = preg_replace_callback(
    '/(?<=cc_number=)([^&]+)/',
    function ($matches) { return str_repeat('X', strlen($matches[0])); },
    $data);

However, I would like to get the ideal option using pure regexp.
Something like Is this possible? Will recursion be required?
$data = preg_replace($pattern, 'X', $data);

Answer the question

In order to leave comments, you need to log in

10 answer(s)
1
1x1, 2013-04-04
@evgabd

s/(?<=cc_number=)|\G\d/X/g

As far as I remember \G is supported in PHP.

F
FilimoniC, 2013-04-03
@FilimoniC

Do you work in a PCI certified office?
If not, then you do not have the right to request CVV\CVC and card number. You can store the card in the format “First six + last four”, this is allowed for transmission in clear text.
When it comes down to it, why do you even need to know the length of the card number? Replace simply with "HIDDEN"

V
Vampiro, 2013-04-03
@Vampiro

To write to the log, it's better to do something like this:
cc_number=HIDDEN_CC_NUMBER&amount=1500&CVV=HIDDEN_CVV Otherwise
, in a couple of weeks you will sculpt regular expressions for searching in the logs 3-4-12-14-16 consecutive "X"

S
SleepingLion, 2013-04-03
@SleepingLion

s/(?<=cc_number=)?(\d)/X/g;
Perl notation, not sure about PHP's specific form of notation.

S
SleepingLion, 2013-04-03
@SleepingLion

Try
$data=preg_replace_all('(?<=cc_number=)?(\d)','X',$data);

E
evgabd, 2013-04-03
@evgabd

(deleted, not answered in the right place)

M
Maxim Ivanushchik, 2013-04-03
@makis

Is it possible to access the $_POST array?
If yes, then you can try to do without a regular expression.

$data = str_replace('cc_number='.$_POST['cc_number'], 'cc_number='.str_repeat('X', strlen($_POST['cc_number'])), $data);

P
Push_Ok, 2013-04-03
@Push_Ok

there was a wrong comment

J
Jonh Doe, 2013-04-03
@CodeByZen

Exceptional how to play. Still preferable with a callback.

$data[1] = "cc_number=1234567890123456&amount=1500";
$data[2] = "cc_number=12345678901234&amount=1500";
$data[3] = "amount=1500&cc_number=12345678901234&otherNumber=123123123";

$patterns = array ('/\d{16}/','/\d{14}/');
$replace = array ('xxxxxxxxxxxxxxxx','xxxxxxxxxxxxxx');
echo preg_replace($patterns, $replace, $data[1]);
echo "<br>";
echo preg_replace($patterns, $replace, $data[2]);
echo "<br>";
echo preg_replace($patterns, $replace, $data[3]);

D
Dmitry Pyatkov, 2013-04-04
@dkrnl

IMHO, it's safer like this:

<?php
$data = parse_str($data);
 if (isset($data["cc_number"])) {
    $data["cc_number"] = str_repeat("X", strlen($data["cc_number"])); 
} 
$data = http_build_query($data);
?>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question