public function rule_credit_card($a)
    {
        // Card formats keep changing and there is too high a risk
        // of false negatives if we get clever. So we just check it
        // with the Luhn Mod 10 formula

        // Calculate the Luhn check number

        $msg = 'Not a valid card number';

        $sum = 0;
        $alt = false;

        for ($i = strlen($a) - 1; $i >= 0; --$i) {
            $n = substr($a, $i, 1);
            if ($alt) {
                //square n
                $n *= 2;
                if ($n > 9) {
                    //calculate remainder
                    $n = ($n % 10) + 1;
                }
            }
            $sum += $n;
            $alt = !$alt;
        }

        // If $sum divides exactly by 10 it's valid

        if (!($sum % 10 == 0)) {
            return $this->fail($msg);
        } else {
            // Luhn check seems to return true for any string of 0s

            $stripped = str_replace('0', '', $a);

            if (strlen($stripped) == 0) {
                return $this->fail($msg);
            }
        }
    }