C# Validating User Input like a Credit Card number
You can use the following method, which will validate all the credit card info as per your requirements.
<1> Credit card number must be 16 digits; the first 4 digits must be one of these: 1298, 1267, 4512, 4567, 8901, 8933
<2> Security code must be 3 digit numeric (assumed)
<3> Expiration date must be 2 digits for the month, <4> 4 digits for the year. <5> The month must be 01 - 12. <6> The year must begin with "20". <7> The date must be greater than the current actual month and year, and <8> less than 6 years from the current actual month and year.
public static bool IsCreditCardInfoValid(string cardNo, string expiryDate, string cvv)
{
var cardCheck = new Regex(@"^(1298|1267|4512|4567|8901|8933)([\-\s]?[0-9]{4}){3}$");
var monthCheck = new Regex(@"^(0[1-9]|1[0-2])$");
var yearCheck = new Regex(@"^20[0-9]{2}$");
var cvvCheck = new Regex(@"^\d{3}$");
if (!cardCheck.IsMatch(cardNo)) // <1>check card number is valid
return false;
if (!cvvCheck.IsMatch(cvv)) // <2>check cvv is valid as "999"
return false;
var dateParts = expiryDate.Split('/'); //expiry date in from MM/yyyy
if (!monthCheck.IsMatch(dateParts[0]) || !yearCheck.IsMatch(dateParts[1])) // <3 - 6>
return false; // ^ check date format is valid as "MM/yyyy"
var year = int.Parse(dateParts[1]);
var month = int.Parse(dateParts[0]);
var lastDateOfExpiryMonth = DateTime.DaysInMonth(year, month); //get actual expiry date
var cardExpiry = new DateTime(year, month, lastDateOfExpiryMonth, 23, 59, 59);
//check expiry greater than today & within next 6 years <7, 8>>
return (cardExpiry > DateTime.Now && cardExpiry < DateTime.Now.AddYears(6));
}
Though this works fine for all the conditions, please check properly before using in production.
Related videos on Youtube
Aaron Cannon
I grew up playing with video games and gadgets, and now I would look to put my experience to good use. I am currently studying at the DATC to become a programmer. On the Coursework page you will find information about the classes I have taken so far and which classes I will take in the future. The Projects page is where I will highlight the various programming projects I have worked on. Finally, you can request a resume on the About page.
Updated on June 04, 2022Comments
-
Aaron Cannon almost 2 years
This is for an assignment. I need to create a program for a sandwich shop. Part of it is to validate a user's payment info. The guidelines for this assignment are
Credit card number must be 16 digits; the first 4 digits must be one of these: 1298, 1267, 4512, 4567, 8901, 8933
Expiration date must be 2 digits for the month, 4 digits for the year. The month must be 01 - 12. The year must begin with "20". The date must be greater than the current actual month and year, and less than 6 years from the current actual month and year.
I have a text box for each number, txtCardNumber, txtSecuritycode, and txtExpiration. What I have works, but I think it's kind of messy. What would be a better way? And would it be possible to have only one
Validate()
method instead of a separate one for each?public bool IsValidCard() { if (txtCardNumber.Text.StartsWith("1298") || txtCardNumber.Text.StartsWith("1267") || txtCardNumber.Text.StartsWith("4512") || txtCardNumber.Text.StartsWith("4567") || txtCardNumber.Text.StartsWith("8901") || txtCardNumber.Text.StartsWith("8933")) { if (Regex.Replace(txtCardNumber.Text, @"\s+", "").Length == 16) { return true; } } return false; }//end IsValidCard() public bool IsValidSecurityCode() { bool isValid = Regex.Match(txtSecurityCode.Text, @"^\d{3}$").Success; return isValid; }//end IsValidSecurityCode() public bool IsValidExpiration() { string[] date = Regex.Split(txtExpiration.Text, "/"); string[] currentDate = Regex.Split(DateTime.Now.ToString("MM/yyyy"), "/"); int compareYears = string.Compare(date[1], currentDate[1]); int compareMonths = string.Compare(date[0], currentDate[0]); //if expiration date is in MM/YYYY format if (Regex.Match(txtExpiration.Text, @"^\d{2}/\d{4}$").Success) { //if month is "01-12" and year starts with "20" if (Regex.Match(date[0], @"^[0][1-9]|[1][0-2]$").Success) { //if expiration date is after current date if ((compareYears == 1) || (compareYears == 0 && (compareMonths == 1))) { return true; } } } return false; }//end IsValidExpiration
Note: I haven't worked on validating the six year requirement.
-
WalterM over 8 yearsdon't forget the checksum en.wikipedia.org/wiki/Luhn_algorithm
-
Arghya C over 8 yearsYou can use
^(1298|1267|4512|4567|8901|8933)([\-\s]?[0-9]{4}){3}$
for credit card number,^(0[1-9]{1}|1[0-2]{1})$
for month and^20[0-9]{2}$
for year. Once these are validated, you need to check the 6 year condition, which depends on current date and cannot be done withRegex
. -
Aaron Cannon over 8 years@WalterM, the Luhn algorithm is pretty sweet, but probably overkill for my purposes.
-
Aaron Cannon over 8 years@ArghyaC, thanks, that makes my IsValidCard() method a little cleaner.
-
Arghya C over 8 years@AaronCannon I have added a method, have a look. It's much cleaner & compact, and does all the validations.
-
Ananke over 8 yearsIs an OO approach expected for this assignment?
-
Aaron Cannon over 8 years@Ananke OO was not mentioned in the assignment requirements, but I did create an object class for a different part of the assignment.
-