Creating Fake Credit Card Numbers in c#

August 16, 2009 4 comments

I recently had to create a credit card number generator, nothing nefarious, just we needed unique valid credit card numbers after asking on StackOverflow and getting a less than stellar response (for the first time). I came across something on DarkCoding.Net which did exactly what I wanted but was in Java, I’ve ported it over to c# and I hope you find it useful

Update

I recently rewrote this code. removing a couple of bugs and making it a bit more c# and bit less Java

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace CreditCardNumberGenerator
{
	public class RandomCreditCardNumberGenerator
	{
		/*This is a port of the port of of the Javascript credit card number generator now in C#
		* by Kev Hunter https://kevhunter.wordpress.com
		* See the license below. Obviously, this is not a Javascript credit card number
		 generator. However, The following class is a port of a Javascript credit card
		 number generator.
		 @author robweber
		 Javascript credit card number generator Copyright (C) 2006 Graham King
		 graham@darkcoding.net
		 This program is free software; you can redistribute it and/or modify it
		 under the terms of the GNU General Public License as published by the
		 Free Software Foundation; either version 2 of the License, or (at your
		 option) any later version.
		 This program is distributed in the hope that it will be useful, but
		 WITHOUT ANY WARRANTY; without even the implied warranty of
		 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
		 Public License for more details.

		 You should have received a copy of the GNU General Public License along
		 with this program; if not, write to the Free Software Foundation, Inc.,
		 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
		 www.darkcoding.net
		*/


		public static string[] AMEX_PREFIX_LIST = new[] {"34", "37"};


		public static string[] DINERS_PREFIX_LIST = new[]
		                                            	{
		                                            		"300",
		                                            		"301", "302", "303", "36", "38"
		                                            	};


		public static string[] DISCOVER_PREFIX_LIST = new[] {"6011"};


		public static string[] ENROUTE_PREFIX_LIST = new[]
		                                             	{
		                                             		"2014",
		                                             		"2149"
		                                             	};


		public static string[] JCB_15_PREFIX_LIST = new[]
		                                            	{
		                                            		"2100",
		                                            		"1800"
		                                            	};


		public static string[] JCB_16_PREFIX_LIST = new[]
		                                            	{
		                                            		"3088",
		                                            		"3096", "3112", "3158", "3337", "3528"
		                                            	};


		public static string[] MASTERCARD_PREFIX_LIST = new[]
		                                                	{
		                                                		"51",
		                                                		"52", "53", "54", "55"
		                                                	};


		public static string[] VISA_PREFIX_LIST = new[]
		                                          	{
		                                          		"4539",
		                                          		"4556", "4916", "4532", "4929", "40240071", "4485", "4716", "4"
		                                          	};


		public static string[] VOYAGER_PREFIX_LIST = new[] {"8699"};

		/*
      'prefix' is the start of the 	CC number as a string, any number
		private of digits	'length' is the length of the CC number to generate.
	 * Typically 13 or	16
		*/
		private static string CreateFakeCreditCardNumber(string prefix, int length)
		{
			string ccnumber = prefix;

			while (ccnumber.Length < (length - 1))
			{
				double rnd = (new Random().NextDouble()*1.0f - 0f);

				ccnumber += Math.Floor(rnd*10);

				//sleep so we get a different seed

				Thread.Sleep(20);
			}


			// reverse number and convert to int
         var reversedCCnumberstring = ccnumber.ToCharArray().Reverse();

			var reversedCCnumberList = reversedCCnumberstring.Select(c => Convert.ToInt32(c.ToString()));

			// calculate sum

			int sum = 0;
			int pos = 0;
			int[] reversedCCnumber = reversedCCnumberList.ToArray();

			while (pos < length - 1)
			{
				int odd = reversedCCnumber[pos]*2;

				if (odd > 9)
					odd -= 9;

				sum += odd;

				if (pos != (length - 2))
					sum += reversedCCnumber[pos + 1];

				pos += 2;
			}

			// calculate check digit
			int checkdigit =
				Convert.ToInt32((Math.Floor((decimal) sum/10) + 1)*10 - sum)%10;

			ccnumber += checkdigit;

			return ccnumber;
		}


		public static IEnumerable<string> GetCreditCardNumbers(string[] prefixList, int length,
		                                          int howMany)
		{
			var result = new Stack<string>();

			for (int i = 0; i < howMany; i++)
			{
				int randomPrefix = new Random().Next(0, prefixList.Length - 1);
	
				if(randomPrefix>1)
				{
					randomPrefix--;
				}

				string ccnumber = prefixList[randomPrefix];

				result.Push(CreateFakeCreditCardNumber(ccnumber, length));
			}

			return result;
		}


		public static IEnumerable<string> GenerateMasterCardNumbers(int howMany)
		{
			return GetCreditCardNumbers(MASTERCARD_PREFIX_LIST, 16, howMany);
		}


		public static string GenerateMasterCardNumber()
		{
			return GetCreditCardNumbers(MASTERCARD_PREFIX_LIST, 16, 1).First();
		}

		public static bool IsValidCreditCardNumber(string creditCardNumber)
		{
			try
			{
				var reversedNumber = creditCardNumber.ToCharArray().Reverse();
				
				int mod10Count = 0;
				for (int i = 0; i < reversedNumber.Count(); i++)
				{
					int augend = Convert.ToInt32(reversedNumber.ElementAt(i).ToString());

					if (((i + 1)%2) == 0)
					{
						string productstring = (augend*2).ToString();
						augend = 0;
						for (int j = 0; j < productstring.Length; j++)
						{
							augend += Convert.ToInt32(productstring.ElementAt(j).ToString());
						}
					}
					mod10Count += augend;
				}

				if ((mod10Count%10) == 0)
				{
					return true;
				}
			}
			catch
			{
				return false;
			}
			return false;
		}
	}
}
Advertisements
Categories: Uncategorized

The Joys Of Interviews

July 22, 2009 Leave a comment

In last couple of weeks we have been interviewing new contractor candidates. The standard has been pretty good with a few notable exceptions;

  1. If you say you find multi-threading easy yet do not know what the lock statement does I tend not to believe you are any good at it.
  2. If you have six years experience in c# and describe your competence as excellent, you really should know the difference between abstract and sealed.

People who need to revise for a simple OO test make me shudder.

Categories: Development Tags: ,

Hiring again

We’re hiring again at work, getting some contractors in to help us with the deliverables in the next three to six months. From the last time we were interviewing the standard seems to be significantly higher, which I imagine is due to not as many companies taking on contractors. I have heard about people despairing over the standard of .Net developers but I have noticed that many more seem to have an understanding of mocking, testing and the SOLID principles than even a year ago.

So many CV’s came in we changed our hiring process and asked sent the applicants a single method to improve maintainability and email us the results, the standard was pretty high (although the original code was really bad) but I think it will give us a good starting point to discuss with the candidates we get in for interview.

As someone involved in the hiring process we can now afford to be more selective, I have found with our current hiring process we have a reasonably simple multiple choice OO which as perhaps a little too much trivia and a very simple practical which I don’t think that this is enough to really understand how good the candidate is, I would rather that they thought more rationally about design and maintainability than knew their way around SqlCommand and the SqlDataReader.

For any candidate we interview, they should understand unit testing, IOC, separation of concerns, know why large classes and methods are wrong and expect to write code in the interview, not being able to write code under pressure is not a reasonable response. We won’t give them FizzBuzz but might ask them to solve a problem on the whiteboard.

Lastly, if I am interviewing you, one last piece of advice, don’t suggest that I use DataSet’s in my Domain Objects we have enough of that sort of architecture here already!

What’s your interview process and has it changed over the last couple of years?

Categories: Development Tags: ,

Can you still be a single platform developer?

June 27, 2009 Leave a comment

When I joined my current company two years ago, I joined specifically as a Winforms developer. At that time the company had seperate Winforms, Web and Service teams within the development department. Within a year this had changed into one cross functional team working on various projects, so I am now exposed to more web programming (ASP.NET 2.0/3.5)  than I expected.

This is definitely a good thing and although I have struggled with some of the challenges of working with a stateless model I am getting to grips with writing the code and getting my ideas out there. I feel a more rounded developer and a more useful team member.

But I was thinking today about if people are still ‘web only’ or ‘winforms’ only developers I think even as little as two years ago that may have been the case. Now I am not sure that you can afford to be. Or if you are, you’re much better off on the web side of the fence. That said, I can never imagine telling a current or prospective employer that I would not be willing to work on a technology even in good times.

I suspect the answer is, and this is from no scientific reasoning and a few Stella’s, that while you still can be a single platform developer, you probably shouldn’t be. The Pragmatic Programmer tells us to learn a new language every year, with the amount of new technology that comes from Microsoft every year perhaps you may just need to learn a new platform.

definitely

Categories: Development Tags: ,

Listen to your onsite customer

June 22, 2009 2 comments

Recently we have been rolling out a project at work which has been in the planning stages and worked on for about 6-8 months off and on. Once the main development had started we made sure that we had regular updates with the main stakeholder. This involved a meeting once a week to show our progress discuss what they liked and didn’t like and which changes they would like to make.

The project is now ready for deployment and we are meeting a lot of resistance from the business. Our main customer seemed pleased with the product and was happy as the iterations when by, however the actual end users seem much less pleased.

I heard recently that if you don’t succeed, make sure you learn from your failure, I assume that some sort of middle ground will eventually be found and that the project will be delivered, but there are a couple of things that I will be taking away from this project.

  1. Make sure that the drops of your code are seen by as many people as possible, especially the people who will be working with the project every day
  2. Early design and mock-ups to let customers know the planned UI are very useful, I have heard good things about Balsamiq for putting together mock designs quickly
  3. Make sure you are prepared to listen to what the customer wants from the very start, rather than letting the design be dictated by the technology

Much of the work I do is with services and apps without a UI so I don’t need to worry about the human interaction, the next time I do I will be ensuring that I and my team will not be making the same mistakes again

Categories: agile Tags: