Checking Credit Card Numbers

Recently as part of the course work through Viking Code School we have been designing data models and their relationships. As practice we designed a basic model of all the entities, attributes, and relationships that you might have to set up for a site similar to Amazon. One question, or point of interest really, that came up was how to handle credit card data. While it was outside of the scope of the project we were informed that companies really don’t store customers’ credit card data. Instead they pass it along to a company that specializes in payment processing. That isn’t to say that these companies don’t provide any checks of their own. You may have entered your card on a website and gotten a notification that the card number you entered was invalid. How does the site know? Do they forward your input to a payment processing company who informs them?

At least for credit card numbers there is a simple check that companies can employ to make sure that entered card numbers  are valid. They can do so by utilizing the Luhn Algorithm. The Luhn Algorithm checks a numbers validity by starting with the last digit, moving towards the first, doubling every even digit, and adding up the resulting product’s digits if the product is greater than 9, and then adding all even and odd digits and checking if the last digit of the total is a 0 (valid) or not (invalid). For instance, if you were given 2683, you would start with 4 (an odd digit), move to 8 (an even digit), double 8, resulting in 16, sum the digits, resulting in 7, and then repeat the process moving forward.

This process would look something like this:

  • 2683
  • 3 stays 3 since it is an odd number
  • 8 becomes 16 after being doubled because it is an even number
  • 16 becomes 7 because you sum the digits if it is over 9
  • 6 stays 6 since it is an odd number
  • 2 becomes 4 after being doubled because it is an even number
  • 6 stays 6 because it is less than 9 after doubling
  • the resulting numbers are (4673)
  • the sum of all these is 20
  • 20 ends in 0 (is evenly divisible by 10)
  • the number is valid

An elegant check that can apply to any credit card of any length (obviously companies have their own standards regarding card length and leading digits).

To implement the Luhn algorithm in Ruby we can do this by:

  • reversing the original number
  • use two separate sums (one for the even digits and one for the odds)
  • slicing the number by an increment of 2 (a handy array method in Ruby)
  • adding the odd digits to the first sum
  • manipulating the even digits accordingly and then adding them to the second sum
  • adding the two sums together
  • and finally, checking whether the total is evenly divisible by 10

The code for this would look something like this:

def luhn(code)
  if code[/[0-9]+/]  != code
    false
  else
    s1 = s2 = 0
    code.to_s.reverse.chars.each_slice(2) do |odd, even| 
      odd = odd.to_i
      even = even.to_i
      s1 += odd
 
      even * 2 >= 10 ? s2 += even * 2 - 9 : s2 += even * 2
    end
    (s1 + s2) % 10 == 0
  end
end

Look at that each_slice method helping us out a ton!

There are many different ways to implement the Luhn algorithm. I preferred this method because it doesn’t utilize any additional memory, besides the two sums, and because it iterates through the number once.

 

Advertisements

Peace Through Programming

Before I officially started the Viking Code School immersive program I had a grand vision of completing projects every day. A vision of taking on and conquering problem after problem. Before starting the bootcamp I was unsure of what I didn’t know but thought I was well on my way there. They describe this learning process as drinking through a firehose. I definitely did not give that analogy enough credit before starting the program. I can say, having just hit the quarter mark, that this is an apt analogy. I start learning something, feel like I understand it, start an intense projects that easily pushes the bounds of what I thought I understood, pushes me into it for hours on end, and then, before you complete the project, you are out of time and on to something new.

That may not sound pleasant, and in a way it really isn’t. I do believe though that being pushed out of my comfort zone every second of everyday I have been at Viking has been beneficial. Not only have I learned a great deal, but I am continuously building on top of it and forcing it to evolve. During the weekend I have homework and work and reflect on some promising projects that were started during the week that were inevitably left unfinished. It is during this time that the pressure from the firehose turns off and I can truly appreciate how much I have grown and understood. It feels hard to accept the pace but letting it envelope me has been great.

I started at Viking because I want to be a web developer and to learn programming. I am definitely doing that. I am also gaining a lot of insight about my limitations, how to adjust for those, how to accept that I don’t know things and then push myself into the unknown instead of doing more reading. I can appreciate that I feel the need to finish everything and not give in to it. One of the best things I have forced myself to do is to accept these facts and it has allowed me to do a couple of things that have made this experience more rewarding and enjoyable.

First, I have learned to take it slow, and not rush to finish a project. Yes, it would be ideal to finish a project and have it beautifully written and fully functional. However, this program is designed so you are always being pushed to your limits, which means most projects don’t end up this way. I have found it much more satisfying and beneficial to not only practice the concepts but also to practice writing good clean code that is modular in design. We have had many projects and every once in awhile we will need to reference or reuse some functionality from a previous project. I am so much more grateful for a project that I started that was finished 75% of the way but was written well than for a project that was completed 100% but is just plain questionable coding.

Second, it has allowed me to enjoy the journey a lot more. At first I was constantly worrying that I didn’t understand the material well enough to recite it in my sleep, or that I wasn’t finishing projects and what that meant for my ability to perform in the real world. Maybe it is that I have completed four weeks, but I have learned to not give in to these feelings so much and take a step back, look at the wonderful projects I am building day in and day out and to recognize and appreciate that I am doing what I want to be doing, that I am following a dream. My dream wasn’t to be a web developer, that was a goal, my dream was to learn to program, and I am currently doing that!

Definitely I have enjoyed my short time at Viking already, and I already feel like I know more than I ever thought I could. I think something I wasn’t prepared for coming in to it though was learning some really great life lessons about focusing on doing good work and enjoying the process. It becomes a lot more easy to roll with the punches when you can give yourself and your experience the credit that it deserves. If you are pursuing a career in programming a code school will definitely teach you what you need to know, and then some.

Recursive Functions

It seems that a lot of people have trouble wrapping their mind around recursion initially. It is definitely a difficult concept to wrap your mind around, especially if you are not accounting for the process that it is undertaking and how the program ultimately works once it reaches its base case. The most important thing to understand is that the first function will not resolve itself until all function calls after it have been resolved. This can be easily seen by a method such as this cascade printing method:

def cascade(num)
  if num < 10
    puts num
  else
    puts num
    cascade(num/10)
    puts num
  end
end

The output when calling this function on 1234567 looks something like this:

1234567
123456
12345
1234
123
12
1
12
123
1234
12345
123456
1234567

The reason this work is because num’s original value, and all subsequent values are stored in that function call and will be stored until the final frame resolves itself. After that happens all the other instances of cascade can finish by printing whatever num they were passed as an argument. To see this in action you can check out the step-by-step process here: cascade

If you want to check out more recursive methods in action you can check these out as well:

factorial

palindrome

sum digit

Recursive factions can be quite useful and can actually be much more elegantly written than their iterative counterparts. While the functions above were purposefully verbose so line execution could be easily followed they can also be written much more simply. For instance a recursive factorial function could be written with a ternary like so:

def factorial(n)
n == 0 ? 1 : n* factorial(n-1)
end

or sum digit:

def sumdig(n)
n < 10 ? n : n % 10 + sumdig(n/10)
end

Beautiful! Recursive functions can be useful but they also have the drawback of being memory intensive if you have a lot of unresolved function calls. For this reason recursive functions are much more prone to causing a stack overflow. Overall recursive functions behave just like any other process, they are just calling themselves. Nothing scary, and can be actually pretty nice and fun to write if you can understand the basic steps of what is happening!

Viking Code School: Week 2

A digit root of a non-negative number is the value obtained by an iterative summing of the original number’s digits. On each iteration using the sum of the previous iteration to compute the next number until the sum is a single digit. Meaning the number 32967’s digit sum is 9 and is achieved in two summations (32967 => 27 => 9). Continue reading

Viking Code School: Week 1

It has been a while since I have written anything here. I am applied and was accepted to the immersive program through Viking Code School and am completing my first full week of intense (seriously) studying. To prepare for the technical interview I solved a lot of Project Euler problems, I think around 20 of them, while recording myself verbally walking myself through the steps. After I completed each problem I would then listen back, take notes on areas I thought I could improve upon and tracked those changes. Another thing that I think also helped me a lot was coding in my head. I would usually do this while at work or when I went running in the mornings. I would pick a problem and then try to work through it without the ability to record what I had already said, thought, or decided. Back to the schooling though. They aren’t joking when they say it is like trying to drink from a firehose. It is overwhelming, difficult, and exhilarating. Being pushed at such a high pace, programming in pairs, and needing to focus intensively made me feel like I was falling behind. However, yesterday was my first weekend day without class and taking a step back I could easily see and appreciate the difference the first week made. I definitely felt much more comfortable writing programs in Ruby. This is going to be insane. I know it. I’m excited for it. I love it. I will try to keep this updated to cover more of the specifics of what we are learning in future posts. Just as a quick overview this past week we covered classes (top to bottom, anything from introductory information to instance variables to inheritance and scope), how to create gems, and testing using RSpec. We accomplished this through detailed readings and 35 hours of actively pair programming.

Project Euler Solutions

I wrote these programs to find solutions to Project Euler problems. It is amazing to me what I can do with Ruby using the basic bits of code that I know. I will come across a problem, think, ‘There is no way I can do that!,’ stick with it, and come up with a solution to the problem. Programming is turning out to be really rewarding, I am definitely enjoying all aspects of it, even getting stuck and figuring my way out of it is really fulfilling for me. Continue reading