Encryption of card number

i have a file with a : separated sections

ABC::2110.49:2110.49:31034050545::+DEF:FPT:2:N::::1:42.99:0.00:2008-07-11:CN:4658582030164342::1:N:afram:N:AI:00220600:S3FA'
XYZ:31034050694:3:::TFY:1:TL1::D:N:42.99:P:9:S:1:18.21:Y:0.00'
JKI:::OC::D:N:2.00::::2::Y::::::2008-07-11'

here 4658582030164342 is a card number(16 digits) i need to encrypt the number such that only first four and last six digit are
visible, that is the remaining six digit to be replaced by ******. that is

4658******164342

The output need to be

ABC::2110.49:2110.49:31034050545::+DEF:FPT:2:N::::1:42.99:0.00:2008-07-11:CN:4658******164342::1:N:afram:N:AI:00220600:S3FA'
XYZ:31034050694:3:::TFY:1:TL1::D:N:42.99:P:9:S:1:18.21:Y:0.00'
JKI:::OC::D:N:2.00::::2::Y::::::2008-07-11'

The card number only appears in the +DEF subsection.
There are several such sections that appear in the file apart from the other data.

To summarise the requirement is check for all the DEF subsection in the file look for 11th field (: separated within DEF) or 16 digit numeric in
DEF section if found encrypt card number as above.

Kindly Advice

Ex. using awk with -F : options.

Block rule something like

/+DEF.*:CN:/ { ... }

Scanning fields ex. using for

 cardnumber=""
 for (f=1;f<=NF;f++) {
     if ( $f == "CN" ) { cardnumber=$(f+1) }
     }

Create result using substr:

 start=substr(cardnumber,1,4)
 end=substr(cardnumber,11,6)
 new=sprintf("%s******%s",start,end)

As ,

Kshj said :

awk -F":" 'BEGIN {OFS=":"} $0 ~/\+DEF.*CN/ {for(i=1;i<=NF;i++) { if($i=="CN"){$(i+1)=substr($(1+i),1,4)"******"substr($(1+i),11,16)}}}1' file_name.txt

Thanks a lot but the issue is here we are checking with DEF section till CN but CN is not the fix two characters that will appear there
it can be any two character

So we have to check for the either the 11th field within DEF separated by : or 16 digit numeric word that appear within DEF section

---------- Post updated at 05:42 AM ---------- Previous update was at 05:38 AM ----------

Additionally it is not that in every DEF section we may get card number, if there is any other data(we can identify it if it is not 16 digit Numeric) we don't need to encrypt

Just a bit modification to the above script :

awk -F":" 'BEGIN {OFS=":"} $0 ~/\+DEF/ {for(i=1;i<=NF;i++) { if($i=="+DEF"){$(i+12)=substr($(12+i),1,4)"******"substr($(12+i)
,11,16)}}}1' file_name.txt

As i checked , the number is the 12th filed from DEF.

Hi Panyam,

its right it is the 12th field but the above code is not working and not encrypting.

---------- Post updated at 06:50 AM ---------- Previous update was at 06:41 AM ----------

Apologise there was an error on my part the above code worked wonder
Thanks a lot panyam and kshij:b:

---------- Post updated at 08:37 AM ---------- Previous update was at 06:50 AM ----------

Last requirement :slight_smile:

i need to encrypt only if the field length is greater than 15

Please Advice

A bit change as follows:

awk -F":" 'BEGIN {OFS=":"} $0 ~/\+DEF/ {for(i=1;i<=NF;i++) { if($i=="+DEF"){if(length($(i+12))>=15) { $(i+12)=substr($(12+i),1,4)"******"substr($(12+i),11,16)}}}}1' 

Not tested.

No panyam that's not working it does not encrypt at all then
Please suggest at your convenient time

You keep using that word. I do not think it means what you think it means.

It is not encrypting the data, it is destroying the data. Perhaps you mean obscuring? I hope so, since there's no way to get it back once that's done except by having an unobscured copy somewhere else.

The code , that i posted working fine for me.

Let me know where you have the issue.

Thanks Panyam that works fine:)

Hi Panyam,
I need to replace or encrypt card only if the item here ($i+12) is numeric
how do i check that

A further enhancement to the script :

awk -F":" '
BEGIN {OFS=":"}
$0 ~/\+DEF/ {
for(i=1;i<=NF;i++)
{
if($i=="+DEF")
{
        if( $(i+12) ~ /[^0-9]/ )
        {
        next;
        }
        else
        {
        if(length($(i+12))>=15)
                {
                $(i+12)=substr($(12+i),1,4)"******"substr($(12+i),11,16)
                }
        }
}
}
}1' file_name.txt