Skip to content

ccyphers/credit_card

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

In order for the Every Day Hero team to evaluated candidates a required
credit card rules based engine should be supplied.  Although, there are
a few errors in the given examples, the underlying wording describing
the algorithm to be implemented was straight forward:

A common check that is performed upfront is to validate the card type based on
the starting digits and length of card number. The main patterns that we care
about are as follows:

+============+=============+===============+
| Card Type  | Begins With | Number Length |
+============+=============+===============+
| AMEX       | 34 or 37    | 15            |
+------------+-------------+---------------+
| Discover   | 6011        | 16            |
+------------+-------------+---------------+
| MasterCard | 51-55       | 16            |
+------------+-------------+---------------+
| Visa       | 4           | 13 or 16      |
+------------+-------------+---------------+

All of these card types also generate numbers such that they can be validated
by the Luhn algorithm, so that's the second check systems usually try. The steps are:

Starting with the next to last digit and continuing with every other digit
going back to the beginning of the card, double the digit
Sum all doubled and untouched digits in the number. For digits greater than 9
you will need to split them and sum the independently (i.e. "10", 1 + 0).

If that total is a multiple of 10, the number is valid.

While I'm not providing comments in the code, specific details about the
implementation are outlined below.

A design decision was made to leave the comments out of the main lib/credit_card.rb
file, since it's summarized here.  If this was a shared code base, where other
developers would be using the library, I would place most of this writeup in the
comments of the library itself.

You might want to start with examining the unit defined by specs/credit_card_spec.rb
to get an idea of the thought process for the solution to the credit card
validation processing.

For running the first check, determining if it's a valid card type, I thought
one good means would be to set constants equal to callback Procs for speed
of execution.  By defining these aspects at run time and not creating
unneeded instances of some other class execution time is enhanced while
maintaining a separation of logic and reuse for other uses.

Since the input data is assumed to be type string, the String class was
extended to provide a member, credit_card_info.  String#credit_card_info
calls CreditCard.details which returns a hash with the format:

{:type => AMEX|Discover|MasterCard|VISA|Unknown, :valid => true|false}

From this hash info one can easily build the required script to read data from
a file and display the results per the problem statement:

ruby bin/credit_card_checker.rb /some/invalid/input/file

    An input file wasn't found.
    Usage: ruby <path to credit_card_root>/bin/credit_card_checker.rb /some/path/to/input_file

ruby bin/credit_card_checker.rb test_data
                VISA  4111111111111111 (valid)
                VISA     4111111111111 (invalid)
                VISA  4012888888881881 (valid)
                AMEX   378282246310005 (valid)
            Discover  6011111111111117 (valid)
          MasterCard  5105105105105100 (valid)
          MasterCard  5105105105105106 (invalid)
             Unknown  9111111111111111 (invalid)

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages