credit card validation routine

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • dries

    credit card validation routine


    A friend of mine has a problem with his credit card validation routine
    and it is probably a simple thing to solve but I cannot find it.
    It has to do with the expiry dates.
    What happens is that as each month passes, that month is then not
    recognised as being valid, even though the year makes it still valid.
    i.e. the number of the month entered has to be bigger than the number
    of the current month. Therefor, if it is in august now 09/2005 wil be
    valid but
    08/2005 will be rejected.
    Below quoted is the code, could anybody make sense of this problem?
    Thanks!



    <HTML>
    <HEAD><TITLE>Se cure Credit Card Transaction</TITLE>
    </HEAD>
    <BODY BGCOLOR="#FFFF0 0">
    <script language="JAVAS CRIPT">
    <!--
    //This function validates entry credit card
    information
    function _vet(){
    var thisyear;
    var thismonth;
    var thisdate;
    var CCname = document.Final. CardHolder.valu e;
    var CCmonth =
    document.Final. ExpMonth.option s[document.Final. ExpMonth.select edIndex].value;
    var CCyear =
    document.Final. ExpYear.options[document.Final. ExpYear.selecte dIndex].value;
    var CCval = document.Final. CCNo.value;
    var CCtype =
    document.Final. CreditCard.opti ons[document.Final. CreditCard.sele ctedIndex].value;
    var failed = false;
    // check if credit card name has been entered
    if (failed == false)
    {
    if (CCname == "")
    {
    alert("Please enter name on card");
    failed = true;
    }
    }

    // check if credit card number has been entered

    if (failed == false)
    {
    if (CCval == "")

    {
    alert ("Please enter credit card number");
    failed = true;
    }
    }

    // check if credit card type has been entered

    if (failed == false)
    {
    if (CCtype == " ")
    {
    alert("Please select credit card type");
    failed = true;
    }
    }

    //Check if card expiry month has been entered

    if (failed == false)
    {
    if (CCmonth == "Mn")
    {
    alert("Please enter credit card expiry month");
    failed = true;
    }
    }

    //Check if card expiry year has been entered

    if (failed == false)
    {
    if (CCyear == "Yr")
    {
    alert("Please enter credit card expiry year");
    failed = true;
    }
    }

    CCval = _strip_spaces(C Cval);

    // check if credit card number is actually a number
    if (_isinteger(CCv al) == false)
    {
    alert("Credit Card number must be a numeric value only
    with or without spaces in between the groups of numbers");
    failed = true;
    }
    if (failed == false)
    {
    // check for 4242 4242 4242 4242

    if (CCval == "42424242424242 42")
    {
    alert ("The credit card number you supplied is
    incorrect");
    failed = true;
    }
    }

    if (failed == false)
    {
    }
    if (failed == false)
    {
    //check that the credit card number is valid
    if (CC_Validate(CC val) == true)
    {

    //now check that the date is valid i.e. greater or equal to now
    thisdate = new Date();
    thisyear = thisdate.getYea r() + 1900;
    thismonth = thisdate.getMon th();
    if ((CCmonth <= thismonth) && (CCyear <=
    thisyear))
    {
    alert("Your credit card has expired");
    failed = true;
    }
    }
    else
    { alert("The credit card number you supplied is
    incorrect");
    failed = true;
    }
    if (failed == false)
    document.Final. submit();
    }
    }

    function _strip_spaces(_ ipstr)
    {
    var _opstr = '';
    var i;
    for (i = 1; i <= _ipstr.length; i++)
    {
    if(_ipstr.subst ring(i-1, i) != ' ')
    _opstr = _opstr + _ipstr.substrin g(i-1, i);
    }
    return _opstr;
    }

    function _isinteger(test _string){
    var i;
    var non_nums = 0;
    for (i = 1; i < test_string.len gth; i++){
    if ((test_string.s ubstring(i-1,i) < '0') ||
    (test_string.su bstring(i-1,i) > '9'))
    non_nums++;
    }

    if (non_nums == 0)
    return true;
    else
    return false;
    }

    function CC_Validate(ccn umber){
    var checksum = 0;
    var i;
    var digit;
    var temp;

    var cclength=ccnumb er.length;
    if (cclength % 2 != 0)
    {
    cclength += 1;
    ccnumber = "0" + ccnumber;
    }

    for (i = 0; i < cclength; i++){
    digit = parseInt(ccnumb er.charAt(i));
    if ((i % 2) == 0){
    digit *= 2;
    if (digit > 9)
    digit = parseInt(digit / 10) + parseInt(digit
    % 10);
    }
    checksum += digit;
    }


    if (checksum % 10 == 0)
    return true;
    else
    return false;
    }

    //-->
    </script>



    <FORM METHOD = "POST" ACTION = "process.cf m" NAME = "Final">
    <INPUT TYPE = "HIDDEN" NAME = "MEMBERSHIP "
    VALUE = " ">
    <INPUT TYPE = "HIDDEN" NAME =
    "APPLICATION_TY PE" VALUE = " ">
    <INPUT TYPE = "HIDDEN" NAME = "TITLE1" VALUE
    = " ">
    <INPUT TYPE = "HIDDEN" NAME = "FIRST_NAME 1"
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "LAST_NAME1 "
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "TITLE2" VALUE
    = " ">
    <INPUT TYPE = "HIDDEN" NAME = "FIRST_NAME 2"
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "LAST_NAME2 "
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "STREET" VALUE
    = "">
    <INPUT TYPE = "HIDDEN" NAME = "TOWN" VALUE =
    "">
    <INPUT TYPE = "HIDDEN" NAME = "REGION" VALUE
    = "">
    <INPUT TYPE = "HIDDEN" NAME = "POST_CODE"
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "COUNTRY" VALUE
    = "">
    <INPUT TYPE = "HIDDEN" NAME = "TELEPHONE_ NO"
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "FAX_NO" VALUE
    = "">
    <INPUT TYPE = "HIDDEN" NAME = "EMAIL_ADDR ESS"
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "COMMENTS"
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "WHERE_FROM "
    VALUE = "">
    <INPUT TYPE = "HIDDEN" NAME = "OTHER" VALUE =
    "">

    <INPUT TYPE="HIDDEN" NAME="SS_TO" VALUE="mail@add ress.com">
    <INPUT TYPE="HIDDEN" NAME="SS_SUBJEC T" VALUE="Membersh ip Credit Card
    Secure Order">
    <INPUT TYPE="HIDDEN" NAME="SS_NEXTPA GE"
    VALUE="http://website/thanks.html">

    <CENTER><FONT FACE="Comic Sans MS" SIZE="+2"
    COLOR="#FF0000" ><B><I>Your Credit Card Details</I></B></FONT></CENTER>
    <BR>
    <FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Please enter your
    Credit Card details below. To avoid any unnecessary delays to your
    order, please verify that all your card details are correct before
    clicking the "Make Payment" button. Thank you.</FONT>
    <HR WIDTH="100%" ALIGN="Center" SIZE="2">

    <table>
    <tr>
    <td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Name On Card
    :</font></td>
    <td><input name="CardHolde r" size=50 maxlength=50></td>
    </tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr>
    <td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Card Number
    :</font></td>
    <td><input name="CCNo" size="25"></font></td>
    </tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr>
    <td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Card Type
    :</font></td>
    <td><select name="CreditCar d">
    <option value=" ">
    <option>VISA
    <option>Masterc ard
    </select></td>
    </tr>
    <tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Expiry Date
    :</font></td>
    <td>
    <FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Month</font>
    <SELECT NAME = "ExpMonth">
    <OPTION VALUE = "Mn">Mn</OPTION>
    <OPTION VALUE = "01">01</OPTION>
    <OPTION VALUE = "02">02</OPTION>
    <OPTION VALUE = "03">03</OPTION>
    <OPTION VALUE = "04">04</OPTION>
    <OPTION VALUE = "05">05</OPTION>
    <OPTION VALUE = "06">06</OPTION>
    <OPTION VALUE = "07">07</OPTION>
    <OPTION VALUE = "08">08</OPTION>
    <OPTION VALUE = "09">09</OPTION>
    <OPTION VALUE = "10">10</OPTION>
    <OPTION VALUE = "11">11</OPTION>
    <OPTION VALUE = "12">12</OPTION>
    </SELECT>
    <FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF" >Year</font>
    <SELECT NAME = "ExpYear">
    <OPTION VALUE = "Yr">Yr</OPTION>
    <OPTION value = "1998">1998 </OPTION>
    <OPTION value = "1999">1999 </OPTION>
    <OPTION value = "2000">2000 </OPTION>
    <OPTION value = "2001">2001 </OPTION>
    <OPTION value = "2002">2002 </OPTION>
    <OPTION value = "2003">2003 </OPTION>
    <OPTION value = "2004">2004 </OPTION>
    <OPTION value = "2005">2005 </OPTION>
    <OPTION value = "2006">2006 </OPTION>
    <OPTION value = "2007">2007 </OPTION>
    <OPTION value = "2008">2008 </OPTION>
    <OPTION value = "2009">2009 </OPTION>
    <OPTION value = "2010">2010 </OPTION>
    </SELECT>
    </td>
    </tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr>
    <td></td>
    <td><INPUT TYPE = "Button" VALUE = " Make Payment" OnClick =
    "_vet()"></td>
    </tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr></tr>
    <tr>
    <td></td>
    <td align=left><INP UT TYPE = "Reset"></td>
    </tr>
    </table>
    </FORM>
    <BR>
    <BR>
    </HTML>

  • Mick White

    #2
    Re: credit card validation routine

    dries wrote:
    [color=blue]
    > A friend of mine has a problem with his credit card validation routine
    > and it is probably a simple thing to solve but I cannot find it.
    > It has to do with the expiry dates.
    > What happens is that as each month passes, that month is then not
    > recognised as being valid, even though the year makes it still valid.
    > i.e. the number of the month entered has to be bigger than the number
    > of the current month. Therefor, if it is in august now 09/2005 wil be
    > valid but
    > 08/2005 will be rejected.
    > Below quoted is the code, could anybody make sense of this problem?
    > Thanks!
    > //now check that the date is valid i.e. greater or equal to now
    > thisdate = new Date();
    > thisyear = thisdate.getYea r() + 1900;
    > thismonth = thisdate.getMon th();
    > if ((CCmonth <= thismonth) && (CCyear <=
    > thisyear))[/color]

    thisdate = new Date();
    thisdate.setMon th(thisdate.get Month()+1)
    thisyear = thisdate.getFul lYear()
    thismonth = thisdate.getMon th();


    if ((CCmonth <= thismonth) && (CCyear <= thisyear))

    I'm not sure about the statement above, but it looks wrong.

    Mick


    Comment

    • jmm-list-gn

      #3
      Re: credit card validation routine

      Mick White wrote:[color=blue]
      >
      > if ((CCmonth <= thismonth) && (CCyear <= thisyear))
      >
      > I'm not sure about the statement above, but it looks wrong.
      >[/color]
      You are correct, it is wrong. It should be:
      if (((CCyear == thisyear) && (CCmonth < thismonth)) ||
      ((CCyear < thisyear)))
      // Expired card. Scissor time.

      --
      jmm dash list (at) sohnen-moe (dot) com
      (Remove .AXSPAMGN for email)

      Comment

      • Dr John Stockton

        #4
        Re: credit card validation routine

        JRS: In article <6lhph0pva6tg21 lj05l5ne1kh95ol trh24@4ax.com>, dated
        Fri, 13 Aug 2004 15:48:35, seen in news:comp.lang. javascript, dries
        <dries@driesbes sels.removebefo reuse.com> posted :[color=blue]
        >
        >A friend of mine has a problem with his credit card validation routine
        >and it is probably a simple thing to solve but I cannot find it.[/color]

        Your friend is not competent enough to be entrusted with financial
        software.
        [color=blue]
        >It has to do with the expiry dates.
        >What happens is that as each month passes, that month is then not
        >recognised as being valid, even though the year makes it still valid.
        >i.e. the number of the month entered has to be bigger than the number
        >of the current month. Therefor, if it is in august now 09/2005 wil be
        >valid but
        >08/2005 will be rejected.[/color]

        I think you mean that it apparently expires one month early.

        [color=blue]
        ><script language="JAVAS CRIPT">[/color]

        Deprecated.
        [color=blue]
        > var CCname = document.Final. CardHolder.valu e;
        > var CCmonth =
        >document.Final .ExpMonth.optio ns[document.Final. ExpMonth.select edIndex].value;
        > var CCyear =
        >document.Final .ExpYear.option s[document.Final. ExpYear.selecte dIndex].value;
        > var CCval = document.Final. CCNo.value;
        > var CCtype =
        >document.Final .CreditCard.opt ions[document.Final. CreditCard.sele ctedIndex].value
        >;[/color]

        Those are strings. Use ... = + ... to get Numbers.
        [color=blue]
        > var failed = false;
        > // check if credit card name has been entered
        > if (failed == false)[/color]

        Should be if (!failed) // throughout.



        [color=blue]
        >//now check that the date is valid i.e. greater or equal to now
        > thisdate = new Date();
        > thisyear = thisdate.getYea r() + 1900;[/color]

        Gives wrong answer on some systems, AIUI. See via FAQ & sig.
        [color=blue]
        > thismonth = thisdate.getMon th();[/color]

        Gives 0..11 - this the problem that you have seen. Add 1.

        [color=blue]
        > if ((CCmonth <= thismonth) && (CCyear <=
        >thisyear))[/color]

        Flawed logic. The simplest fix is to use something like
        if ( CCyear*12 + CCmonth < thisyear*12 + thismonth) // <= ??

        [color=blue]
        >function _isinteger(test _string){
        >var i;
        >var non_nums = 0;
        >for (i = 1; i < test_string.len gth; i++){
        > if ((test_string.s ubstring(i-1,i) < '0') ||
        >(test_string.s ubstring(i-1,i) > '9'))
        > non_nums++;
        > }
        >[/color]
        [color=blue]
        >if (non_nums == 0)
        > return true;
        >else
        > return false;[/color]

        return non_nums == 0 // is simpler.
        [color=blue]
        >}[/color]

        But one can test for all-digit, or whatever, much more easily with a
        RegExp, like

        function isI(S) { return /^\d+$/.test(S) }
        and with \d{m,n} one can bound the length too.

        See <URL:http://www.merlyn.demo n.co.uk/js-valid.htm>.

        [color=blue]
        >function CC_Validate(ccn umber){
        >var checksum = 0;
        >var i;
        >var digit;
        >var temp;[/color]

        Unless you are paid for code by the yard, or in your case metre, there's
        no need to have 4 separate vars. Long code is harder to read.

        [color=blue]
        >var cclength=ccnumb er.length;
        >if (cclength % 2 != 0)
        >{
        > cclength += 1;
        > ccnumber = "0" + ccnumber;
        >}
        >
        >for (i = 0; i < cclength; i++){
        > digit = parseInt(ccnumb er.charAt(i));
        > if ((i % 2) == 0){
        > digit *= 2;
        > if (digit > 9)
        > digit = parseInt(digit / 10) + parseInt(digit
        >% 10);
        > }
        > checksum += digit;
        >}
        >[/color]

        AIUI, parseInt is slow in comparison with unary +.

        parseInt(digit/10) *must* AFAICS give 1.
        digit%10 does not need parseInt.

        I think that d *= 2 ; if (d>9) d-=9 // is sufficient.
        // or if ((d*=2)>9) d-=9
        Compare, though, with an approach based on
        d = [0,2,4,6,8,1,3,5 ,7,9][d]

        It **might** be better to use ccnumber.split( '') - OTOH, it might not.

        BYW, code that is posted to News should not be subject to machine line-
        wrap. It is more efficient for one author to deal with that than for
        several readers. Better to use smaller indent units.

        --
        © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
        <URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang. javascript
        <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
        <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

        Comment

        • dries

          #5
          Re: credit card validation routine

          Thanks for all the comments, I will relay them to the writer!
          Brgds
          Dries

          Comment

          • dries

            #6
            Re: credit card validation routine

            Thanks for all the comments, I will relay them to the writer!
            Brgds
            Dries

            Comment

            • Michael Winter

              #7
              Re: credit card validation routine

              On Fri, 13 Aug 2004 15:48:35 +0200, dries
              <dries@driesbes sels.removebefo reuse.com> wrote:

              [snip]

              Before I start, I'd like to note that this page is an anacronism,
              containing code and practices that should have been abandoned long ago.
              I'd look into CSS and Strict HTML, and catch up with modern web
              development. Also validate your pages: <URL:http://validator.w3.or g/>.

              Finally, when posting code, please don't use tabs. They're inappropriate
              for a medium where a line length limit is in force. Use 2 or 4 spaces for
              each indentation level.
              [color=blue]
              > <HTML>[/color]

              Valid HTML documents should contain a document type declaration. See
              <URL:http://www.w3.org/TR/html401/struct/global.html#h-7.2>.
              [color=blue]
              > <HEAD><TITLE>Se cure Credit Card Transaction</TITLE>[/color]

              JavaScript should be considered an optional element on the Web, and it's
              presence should not be relied upon when it comes to validation. Moreover,
              the execution JavaScript code can be intentionally ignored or manipulated
              in order to falsify results.

              It also appears that the data submitted by this document might be e-mailed
              for further processing. The fact that the transmission to server doesn't
              appear to take place through a secure connection, and that the data is
              subsequently e-mailed means that you cannot hope to describe the process
              as "secure". If this analysis is correct, I would suggest that you cease
              lying to your visitors.
              [color=blue]
              > </HEAD>
              > <BODY BGCOLOR="#FFFF0 0">
              > <script language="JAVAS CRIPT">[/color]

              The language attribute is deprecated. Furthermore, the required type
              attribute makes it redundant. Change this to:

              <script type="text/javascript">
              [color=blue]
              > <!--[/color]

              The practice of script hiding is now obsolete. All browsers in use
              understand what a SCRIPT element is, even if they cannot execute scripts.
              Remove the SGML comment delimiter here, and the closing one, later.
              [color=blue]
              > //This function validates entry credit card
              > information
              > function _vet(){
              > var thisyear;
              > var thismonth;
              > var thisdate;
              > var CCname = document.Final. CardHolder.valu e;
              > var CCmonth =
              > document.Final. ExpMonth.option s[document.Final. ExpMonth.select edIndex].value;
              > var CCyear =
              > document.Final. ExpYear.options[document.Final. ExpYear.selecte dIndex].value;
              > var CCval = document.Final. CCNo.value;
              > var CCtype =
              > document.Final. CreditCard.opti ons[document.Final. CreditCard.sele ctedIndex].value;[/color]

              It would be simpler if you first obtained a reference to the form and
              referenced the controls from that:

              var e = document.forms['Final'].elements,
              CCname = e['CardHolder'].value,
              CCmonth = e['ExpMonth'].options[e['ExpMonth'].selectedIndex].value,
              // etc...
              [color=blue]
              > var failed = false;
              > // check if credit card name has been entered
              > if (failed == false)[/color]

              if(!failed) // if not failed

              [snip]
              [color=blue]
              > //now check that the date is valid i.e. greater or equal to now
              > thisdate = new Date();
              > thisyear = thisdate.getYea r() + 1900;[/color]

              Date.getFullYea r() returns a four-digit year between 1000 and 9999

              thisyear = thisdate.getFul lYear();
              [color=blue]
              > thismonth = thisdate.getMon th();
              > if ((CCmonth <= thismonth) && (CCyear <=[/color]

              Here you're comparing a string, in CCmonth, to a number, in thismonth.
              What's more, the number returned by Date.getMonth() is zero-based, not
              one-based. Even worse is that that comparison will be true for a valid
              date, not an invalid one as intended.

              [snip]
              [color=blue]
              > if (failed == false)
              > document.Final. submit();[/color]

              Validation scripts should not need to call the submit() method. This makes
              the page needlessly dependant upon JavaScript. Instead, you should use a
              submit button and call the script from the FORM element's submit handler,
              returning false if validation failed.

              <script type="text/javascript">
              function validate(form) {
              // test form
              return passed; // Return true if passed, false if failed
              }
              </script>
              <!-- Rest of page -->
              <form ... onsubmit="retur n validate(this)" >
              <!-- Rest of form -->
              <input type="submit" value="Submit">
              </form>
              [color=blue]
              > function _strip_spaces(_ ipstr)[/color]

              [snip]

              This would be better done with a simple regular expression:

              return _ipstr.replace(/\s+/g, '');

              This strips all whitespace. If you want it restricted to only space
              characters, replace "\s" with "\x20".
              [color=blue]
              > function _isinteger(test _string){[/color]

              [snip]

              Again, a regular expression would be better:

              return /^([1-9]|0)[0-9]*$/.test(test_stri ng);

              That ensures that the string contains an integer that cannot have leading
              zeros. To allow any string, as long as it only contains characters 0-9,
              the statement becomes:

              return /^[0-9]+$/.test(test_stri ng);
              [color=blue]
              > if (non_nums == 0)
              > return true;
              > else
              > return false;[/color]

              return (non_nums == 0);
              [color=blue]
              > }
              >
              > function CC_Validate(ccn umber){
              > var checksum = 0;
              > var i;
              > var digit;
              > var temp;
              >
              > var cclength=ccnumb er.length;
              > if (cclength % 2 != 0)
              > {
              > cclength += 1;
              > ccnumber = "0" + ccnumber;
              > }
              >
              > for (i = 0; i < cclength; i++){
              > digit = parseInt(ccnumb er.charAt(i));[/color]

              If the string has already been validated as containing numbers only, it
              would be more efficient to use:

              digit = +ccnumber.charA t(i);

              In any case, you shouldn't call parseInt() with only a single arguement;
              always specify the base.
              [color=blue]
              > if ((i % 2) == 0){
              > digit *= 2;
              > if (digit > 9)
              > digit = parseInt(digit / 10) + parseInt(digit
              > % 10);[/color]

              Now that digit contains a number, what do you expect parseInt() to do?

              digit = (digit / 10) + (digit % 10);

              It should also be noted that arithmetic is not exact in JavaScript, and
              these operations should be rounded.
              [color=blue]
              > }
              > checksum += digit;
              > }
              >
              > if (checksum % 10 == 0)
              > return true;
              > else
              > return false;
              > }[/color]

              return !(checksum % 10);

              [snip]
              [color=blue]
              > <INPUT TYPE="HIDDEN" NAME="SS_TO" VALUE="mail@add ress.com">[/color]

              Any form mail script that asks for the "To" address should be treated with
              suspision. They are often attributed to spam complaints. They also expose
              a valid e-mail address needlessly. I'd find another one.

              [snip]
              [color=blue]
              > <tr></tr>
              > <tr></tr>
              > <tr></tr>
              > <tr></tr>[/color]

              This is invalid HTML. Table rows are required to contain at least one
              table cell (TD) or header (TH).

              [snip]
              [color=blue]
              > <SELECT NAME = "ExpYear">
              > <OPTION VALUE = "Yr">Yr</OPTION>
              > <OPTION value = "1998">1998 </OPTION>
              > <OPTION value = "1999">1999 </OPTION>
              > <OPTION value = "2000">2000 </OPTION>
              > <OPTION value = "2001">2001 </OPTION>
              > <OPTION value = "2002">2002 </OPTION>
              > <OPTION value = "2003">2003 </OPTION>[/color]

              What exactly is the point in specifying the years above? If used, they
              will always evaluate to false.

              [snip]
              [color=blue]
              > <td><INPUT TYPE = "Button" VALUE = " Make Payment" OnClick =
              > "_vet()"></td>[/color]

              I already stated why this was a bad idea.

              [snip]

              To demonstrate the various things I've mentioned here, I've produced a
              page that replicates the original. You can view it at
              <URL:http://www.mlwinter.pw p.blueyonder.co .uk/clj/dries/card.html>. The
              presentation could do with some work, but I don't pretend to be a graphic
              designer. :)

              Good luck,
              Mike

              --
              Michael Winter
              Replace ".invalid" with ".uk" to reply by e-mail

              Comment

              • Dr John Stockton

                #8
                Re: credit card validation routine

                JRS: In article <opscqgitemx13k vk@atlantis>, dated Sat, 14 Aug 2004
                17:35:15, seen in news:comp.lang. javascript, Michael Winter <M.Winter@bl
                ueyonder.co.inv alid> posted :[color=blue]
                >On Fri, 13 Aug 2004 15:48:35 +0200, dries
                ><dries@driesbe ssels.removebef oreuse.com> wrote:[/color]
                [color=blue]
                >Date.getFullYe ar() returns a four-digit year between 1000 and 9999[/color]

                That is so. OTOH it may be misleading (are you thinking of VBscript,
                though the lower limit there is 100?); I believe the range to be
                -271821-04-21 to +275760-09-13; 10^8 days from the start of 1970 GMT.

                Most browsers in current use should have getFullYear.

                [color=blue]
                >In any case, you shouldn't call parseInt() with only a single arguement;
                >always specify the base.[/color]

                In this case, IIRC, the first argument is a single digit string; 1..9
                will be taken as decimal, and 0 as octal, AIUI. Granted, parseInt is
                not needed. It would probably be faster to use charCodeAt and subtract
                48.

                [color=blue]
                >It should also be noted that arithmetic is not exact in JavaScript, and
                >these operations should be rounded.[/color]

                Integer arithmetic is exact when all values remain in the range +-2^53
                inclusive and numbers are divided (/) only by factors. That is the case
                here.

                --
                © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
                <URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang. javascript
                <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
                <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

                Comment

                • Michael Winter

                  #9
                  Re: credit card validation routine

                  On Sun, 15 Aug 2004 13:29:11 +0100, Dr John Stockton
                  <spam@merlyn.de mon.co.uk> wrote:

                  [range of Date.getFullYea r()]
                  [color=blue]
                  > That is so. OTOH it may be misleading (are you thinking ofVBscript,
                  > though the lower limit there is 100?);[/color]

                  No. I took that from the JavaScript reference as it was hand at the time.
                  [color=blue]
                  > I believe the range to be -271821-04-21 to +275760-09-13; 10^8 daysfrom
                  > the start of 1970 GMT.[/color]

                  I calculated a different value, but Opera returns the values you state
                  above. In any event, its of that order of magnitude.
                  [color=blue]
                  > Most browsers in current use should have getFullYear.[/color]

                  It was added to JavaScript in v1.3. I wish the ECMAScript specification
                  noted what was added, when.

                  [parseInt()]
                  [color=blue]
                  > In this case, IIRC, the first argument is a single digit string; 1..9
                  > will be taken as decimal, and 0 as octal, AIUI.[/color]

                  That's what's frequently stated, but it appears to be incorrect.

                  According to ECMA-262, the absence of a second argument, or 0, defaults to
                  base-10. If no explicit radix was specified, an implementation must switch
                  if the length of the string "is at least 2 and the first two
                  characters...ar e either '0x' or '0X'" where it defaults to base-16. If the
                  length of the string "is at least 1 and the first character...is '0'", it
                  is up to the implementation to decide whether to switch to base-8 or use
                  the current base.

                  Granted, most implementations will change to base-8, but there is no
                  guarantee.

                  Note that this does not apply to other methods of conversion, such as
                  unary plus or Number(). In those cases, a "decimal may have any number of
                  leading 0 digits".
                  [color=blue]
                  > Granted, parseInt is not needed. It would probably be faster to use
                  > charCodeAt and subtract 48.[/color]

                  Possibly. I think I'd go for clarity, though.

                  [snip]

                  Mike

                  --
                  Michael Winter
                  Replace ".invalid" with ".uk" to reply by e-mail

                  Comment

                  • Dr John Stockton

                    #10
                    Re: credit card validation routine

                    JRS: In article <opscsda1y0x13k vk@atlantis>, dated Sun, 15 Aug 2004
                    18:20:35, seen in news:comp.lang. javascript, Michael Winter <M.Winter@bl
                    ueyonder.co.inv alid> posted :[color=blue]
                    >
                    >[parseInt()]
                    >[color=green]
                    >> In this case, IIRC, the first argument is a single digit string; 1..9
                    >> will be taken as decimal, and 0 as octal, AIUI.[/color]
                    >
                    >That's what's frequently stated, but it appears to be incorrect.
                    >
                    >According to ECMA-262, the absence of a second argument, or 0, defaults to
                    >base-10. If no explicit radix was specified, an implementation must switch
                    >if the length of the string "is at least 2 and the first two
                    >characters...a re either '0x' or '0X'" where it defaults to base-16. If the
                    >length of the string "is at least 1 and the first character...is '0'", it
                    >is up to the implementation to decide whether to switch to base-8 or use
                    >the current base.[/color]


                    If the only character is '0', it seems silly to interpret it as a
                    special case in decimal, since the octal interpretation gives the same
                    answer.

                    IMHO, ECMA 263 3rd Edn 15.1.2.2, list item 12 allows the radix to be 8
                    or unchanged in this case.

                    Systems interpreting 077 as seventy-seven rather than as sixty-three
                    will no doubt interpret '0' as decimal, though.

                    ECMA evidently does not like leading-zero-means-octal, but cannot
                    disregard precedent.

                    --
                    © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
                    <URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
                    <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
                    <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

                    Comment

                    • Michael Winter

                      #11
                      Re: credit card validation routine

                      On Mon, 16 Aug 2004 11:56:15 +0100, Dr John Stockton
                      <spam@merlyn.de mon.co.uk> wrote:
                      [color=blue]
                      > JRS: In article <opscsda1y0x13k vk@atlantis>, dated Sun, 15 Aug 2004
                      > 18:20:35, seen in news:comp.lang. javascript, Michael Winter
                      > <M.Winter@bluey onder.co.invali d> posted :[/color]

                      [snip]
                      [color=blue][color=green]
                      >> According to ECMA-262, the absence of a second argument, or 0, defaults
                      >> to base-10.[/color][/color]

                      Just to clarify that sentence, I meant to say that an unspecified or zero
                      (0) value for the second argument defaults to base-10.

                      [snip]
                      [color=blue]
                      > If the only character is '0', it seems silly to interpret it as a
                      > special case in decimal, since the octal interpretation gives the same
                      > answer.[/color]

                      If the radix was explicitly specified as 10, no radix switch will occur,
                      no matter what the format of the string. This is true for all explicitly
                      set, valid values for radix. A switch to octal or hexadecimal may only
                      occur if no radix was specified (or specified as zero), and even then,
                      octal is optional.[1]

                      [snip]
                      [color=blue]
                      > ECMA evidently does not like leading-zero-means-octal, but cannot
                      > disregard precedent.[/color]

                      I think that the one and only time I was forced to use octal was when I
                      programmed a Z80 and the mnemonics were listed with octal instruction
                      codes, but they needed to be input in hexadecimal (or vice versa, I
                      forget). However, I couldn't begin to guess at the number of times I've
                      used leading-zero decimal or hexadecimal.

                      It's no great loss that automatic octal interpretation is no longer
                      required in an implemention - a number with a single leading zero can
                      easily be tested with a regular expression and, if found, parseInt can be
                      called with an explicit 8.

                      That said, perhaps it would probably be better to state catagorically yes
                      or no, rather than, "it's up to you".

                      Mike

                      [1] I'm sure that you knew that, but your statement seemed ambiguous, so I
                      wanted to be sure, especially in the light of my own (now rewritten)
                      confused sentence.

                      --
                      Michael Winter
                      Replace ".invalid" with ".uk" to reply by e-mail

                      Comment

                      Working...