Based on my answer here, this will mask the beginning of the number and leave the label, the brackets and the last four digits for card numbers of almost any number of digits:
sed -e 'h' -e 's/.*\([0-9]\{4\}\)/\1/' -e 'x' -e 's/\(.*\[\)\([0-9]*\)\([0-9]\{4\}\)./\1\2/' -e 's/[0-9]/*/g' -e 'G' -e 's/\n//'
If you need to validate that the total number of digits only falls within a given range, that can be done, too.
Edit:
Here's a couple of ways:
Pass through numbers unchanged that are too long or too short:
sed -e '/.*\[[0-9]\{12,19\}\]/!b' -e 'h' -e 's/.*\([0-9]\{4\}\)/\1/' -e 'x' -e 's/\(.*\[\)\([0-9]*\)\([0-9]\{4\}\)./\1\2/' -e 's/[0-9]/*/g' -e 'G' -e 's/\n//'
CARD_NUMBER=[12345678] yields CARD_NUMBER=[12345678]
CARD_NUMBER=[123456789012] yields CARD_NUMBER=[********9012]
CARD_NUMBER=[12345678901234567890] yields CARD_NUMBER=[12345678901234567890]
Mask all digits of numbers that are too long or too short using a different mask character:
sed -e '/.*\[[0-9]\{12,19\}\]/!{s/[0-9]/x/g;b}' -e 'h' -e 's/.*\([0-9]\{4\}\)/\1/' -e 'x' -e 's/\(.*\[\)\([0-9]*\)\([0-9]\{4\}\)./\1\2/' -e 's/[0-9]/*/g' -e 'G' -e 's/\n//'
CARD_NUMBER=[12345678] yields CARD_NUMBER=[xxxxxxxx]
CARD_NUMBER=[123456789012] yields CARD_NUMBER=[********9012]
CARD_NUMBER=[12345678901234567890] yields CARD_NUMBER=[xxxxxxxxxxxxxxxxxxxx]