Tuesday, February 24, 2015

SOFT6008 Class 04.1

Apologies for the late start. My calendar led me astray and I obeyed.

We reviewed various JavaScript versions of the Luhn algorithm found online. Some we didn't like. 

From https://gist.github.com/DiegoSalazar/4075533 (modified by Colin slightly)

This code addresses the problem of strings of unknown length by starting at the end and counting down and keep track of what to do by toggling bEven. However we were initially puzzled by the (nDigit *= 2)  which is both a test and a statement.
function valid_credit_card(value) {
// The Luhn Algorithm. It's so pretty.
var nCheck = 0, nDigit = 0, bEven = false;
 
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
 
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
 
nCheck += nDigit;
bEven = !bEven;
}
 
return (nCheck % 10) == 0;
}
This code was interesting because it used the fact that JavaScript can add an internet to a string and get a string. That's a small bit strange.  The expected test to see if the product of the *2 > 10 isn't there, because the digits will get added up anyway in the second part of the code.
  // Run through each single digit to create a new string. Even digits
  // are multiplied by two, odd digits are left alone.

  t = "";
  for (i = 0; i < r.length; i++) {
    c = parseInt(r.charAt(i), 10);
    if (i % 2 != 0)
      c *= 2;
    t = t + c;
  }

  // Finally, add up all the single digits in this string.

  n = 0;
  for (i = 0; i < t.length; i++) {
    c = parseInt(t.charAt(i), 10);
    n = n + c;
  }



This code handles odd and even length strings even though it starts at the beginning and words forward. The i % 2 == parity) test looks like our i % 2 == 0, except the desired value 0 or 1 is set beforehand, depending on whether the length is ever or odd. 

function checkLuhn(input)
{
  var sum = 0;
  var numdigits = input.length;
  var parity = numdigits % 2;
  for(var i=0; i < numdigits; i++) {
    var digit = parseInt(input.charAt(i))
    if(i % 2 == parity) digit *= 2;
    if(digit > 9) digit -= 9;
    sum += digit;
  }
  return (sum % 10) == 0;
}


The following examples we considered to be too clever and too cryptic. I pointed out that short clever code isn't always a good thing, because the programmer that comes after might not be able to understand it.

https://gist.github.com/ShirtlessKirk/2134376

http://stackoverflow.com/questions/12310837/implementation-of-luhn-algorithm

http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#JavaScript

No comments: