Is there a better way to mask a Credit Card number in python?
Asked Answered
C

10

14

So I have a csv file that contains full credit-card numbers.. We dont need the full number, and so I am writing a quick script to parse through the csv and replace the cc number with a masked representation. (all *'s except the last four). I am pretty new to python and hacked this up, and it works, but in order to learn I want to know if it could be done easier.

Assume that "str" will be a full creditcard number. But for the sake of my example I am just using the string "CREDITCARDNUMBER".

str = "CREDITCARDNUMBER";
strlength = len(str)
masked = strlength - 4
slimstr = str[masked:]
print "*" * masked + slimstr

The output is exactly what I want

************MBER

But I am sure there is a more elegant solution. :) Thanks!

Christianly answered 16/3, 2012 at 1:30 Comment(4)
by looking at this i'm guessing you an shorter the code 1~2 linesOdelia
why not just print the last 4 numbers? are the asterisks necessary?Jenness
You might want to accept one of these answersGeostatic
So far I wouldn't call the answers more "elegant". They are shorter, but a bit cryptic I think. In general I might prefer the code in the question for readability.Rayerayfield
K
23

Neater still:

>>> s = "CREDITCARDNUMBER"
>>> s[-4:].rjust(len(s), "*")
'************MBER'
Kinetics answered 16/3, 2012 at 1:51 Comment(0)
B
10

Perhaps slightly more elegant:

card = "CREDITCARDNUMBER"
print ("*" * (len(card) - 4) + card[-4:])

Note that I've avoided using the name str because that is already the name of the built-in string type. It's usually not a good idea to use names that shadow the built-in names.

Bassist answered 16/3, 2012 at 1:32 Comment(0)
O
9

For those who want to keep Issuer Identification Number (IIN) (previously called the "Bank Identification Number" (BIN)), which is usually the first 6 digits, that should do the job:

print card[:6] + 'X' * 6 + card[-4:]
'455694XXXXXX6539'
Offing answered 2/7, 2013 at 13:2 Comment(0)
C
5

With Format String and Slicings:

'{:*>16}'.format(card[-4:])
Chalmer answered 16/3, 2012 at 6:6 Comment(1)
sweet!, i modified it a bit to deal with dynamic length ('{:*>'+str(len(card) - 4)+'}').format(card[-4:])Dated
C
0

You could make it a little shorter like so:

str = "CREDITCARDNUMBER";
print "*" * (len(str) - 4) + str[-4:];
Corvus answered 16/3, 2012 at 1:35 Comment(0)
P
0

I wanted a flexible way to mask stuff, so I thought I'd share ...

def mask(string, start=0, end=0, chunk=4, char="*"):

    if isinstance(string, str):

        string_len = len(string)

        if string_len < 3:
            return "input len = {}, what's the point?".format(string_len)

        if start <= 0 or end <= 0:
            start = string_len // chunk
            end = start

        if string_len <= 4:
            mask_len = string_len // 2
            start = 1 if mask_len - 1 == 0 else mask_len - 1
            end = start
        else:
            mask_len = string_len - abs(start) - abs(end)

        return string[:abs(start)] + (char * mask_len) + string[-end:]



if __name__ == "__main__":

    s = "abcdefghijklmnopqrstuvwxyz01234567890a0b0c0d0e0f1a1b1c1d1e1f2a2b"
    l = [i for i in s]
    message = "ip: {}\nop: {}\n"
    section = "-"*79

    print("\nSTRINGS")
    print(section)
    print(message.format(s[:4], mask(s[:4])))
    print(message.format(s[:3], mask(s[:3])))
    print(message.format(s[:2], mask(s[:2])))
    print(message.format(s, mask(s)))
    print(message.format(s, mask(s,start=2,end=4,char="#")))
    print(message.format(s, mask(s,start=3,end=3,char="x")))
Photogram answered 15/3, 2018 at 0:1 Comment(0)
R
0

I think you can get a decently readable solution without worrying about the len of the str using a simple regex replace and two string slices:

import re
str = 'CREDITCARDNUMBER'
print(re.sub('.', '*', str[:-4]) + str[-4:])

I am not sure this is more "elegant" than the original, but there it is.

Rayerayfield answered 3/8, 2018 at 0:15 Comment(0)
D
0

We also can use this function:

def maskify(cc):
    if len(cc) < 4:
        return cc
    return "#" * (len(cc)-4) + cc[-4:]
Disini answered 1/6, 2020 at 10:29 Comment(0)
R
0
#Simple code to mask 16-digit credit card number

def cardNumberHider():
    str = input("Enter the card number: ")
    masked = len(str) - 4
    slimstr = str[masked:]
    print("Your masked card number is: ", end="")
    print("*" * masked + slimstr)
cardNumberHider()
Rogerrogerio answered 22/12, 2021 at 15:33 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Boson
F
-1

You could also simplify it further with this:

input = str(input("Enter your credit card number (one continuous number): "))
x = input[12:16]
print("************" + x)
Final answered 23/4 at 3:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.