字符串参数传递给函数-以下是可能的输入数据的各种示例 函数接收此数据作为字符串,而不是数组,json或其他数据格式 该函数应解析字符串并屏蔽敏感数据。 敏感数据应使用Asterix(*)字符屏蔽(替换)。 敏感数据包括以下字段,但应根据需要轻松将新的敏感字段添加到函数中:
信用卡号
信用卡有效期
信用卡CVV值
该函数以与提供的格式相同的格式返回已解析的字符串,但现在已屏蔽了敏感数据。
<?php
$testData1 = "[orderId] => 212939129
[orderNumber] => INV10001
[salesTax] => 1.00
[amount] => 21.00
[terminal] => 5
[currency] => 1
[type] => purchase
[avsStreet] => 123 Road
[avsZip] => A1A 2B2
[customerCode] => CST1001
[cardId] => 18951828182
[cardHolderName] => John Smith
[cardNumber] => 5454545454545454
[cardExpiry] => 1025
[cardCVV] => 100";
$testData2 = "Request=Credit Card.Auth Only&Version=4022&HD.Network_Status_Byte=*&HD.Application_ID=TZAHSK!&HD."
. "Terminal_ID=12991kakajsjas&HD.Device_Tag=000123&07."
. "POS_Entry_Capability=1&07.PIN_Entry_Capability=0&07.CAT_Indicator=0&07."
. "Terminal_Type=4&07.Account_Entry_Mode=1&07.Partial_Auth_Indicator=0&07.Account_Card_Number="
. "4242424242424242&07.Account_Expiry=1024&07.Transaction_Amount=142931&07."
. "Association_Token_Indicator=0&17.CVV=200&17.Street_Address=123 Road SW&17.Postal_Zip_Code=90210&17.Invoice_Number=INV19291";
$testData3 = '{
"MsgTypId": 111231232300,
"CardNumber": "4242424242424242",
"CardExp": 1024,
"CardCVV": 240,
"TransProcCd": "004800",
"TransAmt": "57608",
"MerSysTraceAudNbr": "456211",
"TransTs": "180603162242",
"AcqInstCtryCd": "840",
"FuncCd": "100",
"MsgRsnCd": "1900",
"MerCtgyCd": "5013",
"AprvCdLgth": "6",
"RtrvRefNbr": "1029301923091239",
}';
$testData4 = "<?xml version='1.0' encoding='UTF-8'?>
<Request>
<NewOrder>
<IndustryType>MO</IndustryType>
<MessageType>AC</MessageType>
<BIN>000001</BIN>
<MerchantID>209238</MerchantID>
<TerminalID>001</TerminalID>
<CardBrand>VI</CardBrand>
<CardDataNumber>5454545454545454</AccountNum>
<Exp>1026</Exp>
<CVVCVCSecurity>300</Exp>
<CurrencyCode>124</CurrencyCode>
<CurrencyExponent>2</CurrencyExponent>
<AVSzip>A2B3C3</AVSzip>
<AVSaddress1>2010 Road SW</AVSaddress1>
<AVScity>Calgary</AVScity>
<AVSstate>AB</AVSstate>
<AVSname>JOHN R SMITH</AVSname>
<OrderID>23123INV09123</OrderID>
<Amount>127790</Amount>
</NewOrder>
</Request>";
$parseNew = array("name", "amt", "amount"); //some optional fields to parse
//this function will take a provided string, $data, and replace all credit card information including 16-digit numbers, expiry dates and 3-digit CVV numbers.
//$parseNew is an optional field to parse other sensitive information that matches the type of information entered into $parseNew, such as the transaction amount.
//if the strings in $parseNew matches any field in the data given, then that data will be parsed as well
//assign each piece of given test data to a variable for each to be passed into helcimTest
function helcimTest($data, $parseNew) {
$lines = explode("\n", $data); //split data by new lines into an array
if (count($lines) == 1) { //if there aren't any new lines, then periods are used
$lines = explode(".", $data); //different splits can also be added with another if, like a ,
//print_r($lines);
}
for ($currLine = 0; $currLine < count($lines); $currLine++) { //loop through the lines and check for credit card information keywords as well as if theres any matches in $parseNew
$nonos = array("cvv", "exp", "expiry", "expire", "CVV", "Exp"); //keywords of default fields to be parsed, credit card numbers need to be searched for differently
$nonos = array_merge($nonos, $parseNew); //take optional parse data types and add it to array of default credit card data types
//checking credit card number first
$cardPos = strpos($lines[$currLine], "card"); //find "card" as part of Card Number
if ($cardPos === false) {
$cardPos = strpos($lines[$currLine], "Card");
}
if ($cardPos > 0) { //if "card" is in the line, we check if "number" is also
$numberPos = strpos($lines[$currLine], "Number");
if ($numberPos === false) {
$numberPos = strpos($lines[$currLine], "number");
}
if ($numberPos > 0) {
$matches = array();
preg_match_all('!\d+!', $lines[$currLine], $matches); //grabs all numbers in the line and throws them in an array
$numberLength = 0;
$digits = $matches[0]; //unpack array inside matches array
for ($i = 0; $i < count($digits); $i++) {
if (strlen($digits[$i]) == 16) {
$theNumber = $digits[$i];
$numberLength = strlen($digits[$i]);
}
}
if ($numberLength == 16) { //when all of these things are true then this number is definitely a credit card number
$lines[$currLine] = str_replace($theNumber, "****************", $lines[$currLine]);
//print_r($lines);
}
}
}
//credit card number check complete
//now to check for everythign else
for ($i = 0; $i < count($nonos); $i++) {
$currNono = $nonos[$i]; //current type of data we are looking to parse
if(strpos($lines[$currLine], $currNono) > 0){ //check to see if current parsing field exists on current line
preg_match_all("/\d+\.\d+|\d+|[A-Za-z]+/", $lines[$currLine], $matches);
$sensData = $matches[0]; //unpack array from wihtin another array
print_r($sensData);
for($f = 0; $f < count($sensData); $f++){ //if we find any fields we want to parse
if (strcmp($sensData[$f], $currNono) == true && $f+1 != count($sensData)){
$hash = str_repeat("*", strlen($sensData[$f+1]));
$lines[$currLine] = str_replace($sensData[$f+1], $hash, $lines[$currLine]);
}
}
}
}
}
print_r($lines);
}
echo "Data set 1:\n\n"; //print results
helcimTest($testData1, $parseNew);
echo "Data set 2:\n\n";
helcimTest($testData2, $parseNew);
echo "Data set 3:\n\n";
helcimTest($testData3, $parseNew);
echo "Data set 4:\n\n";
helcimTest($testData4, $parseNew);
输出看起来像这样,某些值已正确解析,有些则感觉完全是随机的。该函数的第一部分仅处理信用卡号,该信用卡号被正确正确地解析,这是当该函数到达其底部一半时,我布置的模式与结果相比毫无意义:>
Data set 1:
Array
(
[0] => amount
[1] => 21.00
)
Array
(
[0] => cardExpiry
[1] => 1025
)
Array
(
[0] => cardCVV
[1] => 100
)
Array
(
[0] => [orderId] => 212939129
[1] => [orderNumber] => INV10001
[2] => [salesTax] => 1.00
[3] => [amount] => 21.00
[4] => [terminal] => 5
[5] => [currency] => 1
[6] => [type] => purchase
[7] => [avsStreet] => 123 Road
[8] => [avsZip] => A1A 2B2
[9] => [customerCode] => CST1001
[10] => [cardId] => 18951828182
[11] => [cardHolderName] => John Smith
[12] => [cardNumber] => ****************
[13] => [cardExpiry] => ****
[14] => [cardCVV] => ***
)
Data set 2:
Array
(
[0] => Account
[1] => Expiry
[2] => 1024
[3] => 07
)
Array
(
[0] => Request=Credit Card
[1] => Auth Only&Version=4022&HD
[2] => Network_Status_Byte=*&HD
[3] => Application_ID=TZAHSK!&HD
[4] => Terminal_ID=12991kakajsjas&HD
[5] => Device_Tag=000123&07
[6] => POS_Entry_Capability=1&07
[7] => PIN_Entry_Capability=0&07
[8] => CAT_Indicator=0&07
[9] => Terminal_Type=4&07
[10] => Account_Entry_Mode=1&07
[11] => Partial_Auth_Indicator=0&07
[12] => Account_Card_Number=****************&07
[13] => Account_******=****&**
[14] => Transaction_Amount=142931&07
[15] => Association_Token_Indicator=0&17
[16] => CVV=200&17
[17] => Street_Address=123 Road SW&17
[18] => Postal_Zip_Code=90210&17
[19] => Invoice_Number=INV19291
)
Data set 3:
Array
(
[0] => CardExp
[1] => 1024
)
Array
(
[0] => CardCVV
[1] => 240
)
Array
(
[0] => {
[1] => "MsgTypId": 111231232300,
[2] => "CardNumber": "****************",
[3] => "CardExp": ****,
[4] => "CardCVV": ***,
[5] => "TransProcCd": "004800",
[6] => "TransAmt": "57608",
[7] => "MerSysTraceAudNbr": "456211",
[8] => "TransTs": "180603162242",
[9] => "AcqInstCtryCd": "840",
[10] => "FuncCd": "100",
[11] => "MsgRsnCd": "1900",
[12] => "MerCtgyCd": "5013",
[13] => "AprvCdLgth": "6",
[14] => "RtrvRefNbr": "1029301923091239",
[15] => }
)
Data set 4:
Array
(
[0] => Exp
[1] => 1026
[2] => Exp
)
Array
(
[0] => CVVCVCSecurity
[1] => 300
[2] => Exp
)
Array
(
[0] => CurrencyExponent
[1] => 2
[2] => CurrencyExponent
)
Array
(
[0] => AVSname
[1] => JOHN
[2] => R
[3] => SMITH
[4] => AVSname
)
Array
(
[0] => <?xml version='1.0' encoding='UTF-8'?>
[1] => <Request>
[2] => <NewOrder>
[3] => <IndustryType>MO</IndustryType>
[4] => <MessageType>AC</MessageType>
[5] => <BIN>000001</BIN>
[6] => <MerchantID>209238</MerchantID>
[7] => <TerminalID>001</TerminalID>
[8] => <CardBrand>VI</CardBrand>
[9] => <CardDataNumber>****************</AccountNum>
[10] => <***>1026</***>
[11] => <CVVCVCSecurity>***</***>
[12] => <CurrencyCode>124</CurrencyCode>
[13] => <****************>*</****************>
[14] => <AVSzip>A2B3C3</AVSzip>
[15] => <AVSaddress1>2010 Road SW</AVSaddress1>
[16] => <AVScity>Calgary</AVScity>
[17] => <AVSstate>AB</AVSstate>
[18] => <*******>**** * *****</*******>
[19] => <OrderID>23123INV09123</OrderID>
[20] => <Amount>127790</Amount>
[21] => </NewOrder>
[22] => </Request>
)
答案 0 :(得分:0)
一个问题:您确定您的XML数据正确吗?
<CardDataNumber>5454545454545454</AccountNum>
应该不是这样的:
<CardDataNumber>5454545454545454</CardDataNumber>
或类似这样:
<AccountNum>5454545454545454</AccountNum>
此行中的相同问题:
<CVVCVCSecurity>300</Exp>
因此,如果您从以下位置更改代码部分:
if (strcmp($sensData[$f], $currNono) == true && $f+1 != count($sensData)){
$hash = str_repeat("*", strlen($sensData[$f+1]));
$lines[$currLine] = str_replace($sensData[$f+1], $hash, $lines[$currLine]);
}
对此:
if ($f > 0 && $f < count($sensData)-1){
$hash = str_repeat("*", strlen($sensData[$f]));
$lines[$currLine] = str_replace($sensData[$f], $hash, $lines[$currLine]);
}
让我解释一下我的解决方案: if语句现在检查$ f是否为0(括号中的第一个匹配项)而不是匹配数-1(因此括号中的最后一个匹配项)。如果是这样,它就是内容,并且会根据Asterix(*)字符的合适长度进行更改。
在“我的测试”中,它可以正常工作,如果有任何疑问,请发表评论!
提示!已与CurrencyExponent匹配,因为它包含 Exp ,如下所示:Currency Exp onent