Forum Moderators: coopster

Message Too Old, No Replies

Grr. credit card masking script

one too many XXXXs

         

lorax

9:15 pm on Jan 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The following code is designed to take a string like this: "Card number: 1111222233334444" and convert it into this: "Card number: XXXX-XXXX-XXXX-4444" and send it along in an email to the Admin of the cart.

The problem is the actual string it's sending back is this: "Card number: XXXX-XXXX-XXXX-XXXX-4444" I can't find the bugger that's causing the extra set of Xs!

Note: the function func_get_modified_details is what starts the process off. $details is passed from a script that calls this function.

function func_expand_string ($s, $count = 4) {
$s = preg_replace("/ /","", $s) ;

if(!$s) return "" ;

if(!is_numeric($count) ¦¦ $count <= 0 ) $count = 4 ;

$arr = preg_split("//",$s, -1, PREG_SPLIT_NO_EMPTY) ;

if($arr && is_array($arr)) {
$tmp = array() ;
$i = 0 ;
foreach($arr as $k=>$v) {
$tmp[$i] .= $v ;
if((($k+1)%$count) == 0 )
$i++ ;
}
}

$return = implode("-", $tmp) ;

return $return ;
}
#
# Credit Card Mask -> XXXX XXXX XXXX 0000
#
function func_get_modified_details ($details) {
preg_match_all("/\\nCard number: (.*)\\n/",$details,$cc) ;

$cc = substr_replace($cc[1][0],str_repeat("X",strlen($cc[1][0])),0, strlen($cc[1][0])-4);
$cc = func_expand_string ($cc) ;
$return = preg_replace("/\\nCard number: (.*)\\n/","\nCard number: ".$cc."\n",$details) ;
return $return ;
}

coopster

12:14 am on Jan 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



You are repeating "X" 16 times, lorax. So it is "squeezing" in an additional 4 X's ;-)

$cc = substr_replace($cc[1][0],str_repeat("X",strlen($cc[1][0])-4),0, strlen($cc[1][0])-4); 

lorax

2:23 am on Jan 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks coop. I knew it had to be simple. I just could see it!

coopster

3:31 am on Jan 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



You betcha.

I created a similar function once for something else so I took that and modified it a bit to show you another path you could use in your implementation. Take or leave it, but here is another example (note: only works in PHP5 because of the str_split function):

function maskCC($n, $b = 4, $p = 16, $m = 'X', $l = 4) 
{
// $n = 'Card number: 1234567890123456' string
// $b = break into how many in each chunk?
// $p = pad to what length?
// $m = mask character?
// $l = leave how many numbers showing?
preg_match [php.net]("/Card number:\s*(\d+)[^\d]*/i", trim($n), $matches);
$pattern = "/Card number:\s*(\d+)/ie";
$replacement = "
implode [php.net]('-',
str_split [php.net](
substr_replace [php.net](
str_pad [php.net]('$1', '$p', '0', STR_PAD_LEFT),
str_repeat [php.net]('$m', $p-$l),
0,
$l * -1
),
$b)
);
";
return preg_replace [php.net]($pattern, $replacement, trim($n));
}
var_dump(maskCC("\nCard number: 1222233334444\n"));

I suppose you could modify it to meet your needs though (replace that str_split function with your own user-defined function for now) if you felt up to it. Anyway, thought I'd throw down another idea for you ...

henry0

12:17 pm on Jan 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I knew yesterday that it was a good idea to flag that thread.

Just shamelessly copied the function!

Thanks

Cheers :)
Henry

vincevincevince

12:41 pm on Jan 19, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Try this :)


$cardno="Card number: 1234567891123456";
print "Card number: XXXX-XXXX-XXXX-".substr($cardno,-4);

jatar_k

4:25 pm on Jan 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I'm with you vincevincevince,

why play around so much when you can just ripoff the last 4 digits and stick them onto a string

coopster

7:35 pm on Jan 19, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I would agree, but in the instance that I first created the function shown I had to return formats differently each time (not for credit card numbers). You can't just rip off the last few digits anymore. That's where the function came in handy.
var_dump(maskCC("\nCard number: 1222233334444\n")); 
// XXXX-XXXX-XXXX-4444
var_dump(maskCC("\nCard number: 111122223333444455\n",4,18,'#',5));
// ####-####-####-#444-55
var_dump(maskCC("\nCard number: 11122233\n",5,12,'*',6));
// *****-*1222-33