472,958 Members | 1,984 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,958 software developers and data experts.

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>Secure Credit Card Transaction</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFF00">
<script language="JAVASCRIPT">
<!--
//This function validates entry credit card
information
function _vet(){
var thisyear;
var thismonth;
var thisdate;
var CCname = document.Final.CardHolder.value;
var CCmonth =
document.Final.ExpMonth.options[document.Final.ExpMonth.selectedIndex].value;
var CCyear =
document.Final.ExpYear.options[document.Final.ExpYear.selectedIndex].value;
var CCval = document.Final.CCNo.value;
var CCtype =
document.Final.CreditCard.options[document.Final.CreditCard.selectedIndex].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(CCval);

// check if credit card number is actually a number
if (_isinteger(CCval) == 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 == "4242424242424242")
{
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(CCval) == true)
{

//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
thismonth = thisdate.getMonth();
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.substring(i-1, i) != ' ')
_opstr = _opstr + _ipstr.substring(i-1, i);
}
return _opstr;
}

function _isinteger(test_string){
var i;
var non_nums = 0;
for (i = 1; i < test_string.length; i++){
if ((test_string.substring(i-1,i) < '0') ||
(test_string.substring(i-1,i) > '9'))
non_nums++;
}

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

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

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

for (i = 0; i < cclength; i++){
digit = parseInt(ccnumber.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.cfm" NAME = "Final">
<INPUT TYPE = "HIDDEN" NAME = "MEMBERSHIP"
VALUE = " ">
<INPUT TYPE = "HIDDEN" NAME =
"APPLICATION_TYPE" VALUE = " ">
<INPUT TYPE = "HIDDEN" NAME = "TITLE1" VALUE
= " ">
<INPUT TYPE = "HIDDEN" NAME = "FIRST_NAME1"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "LAST_NAME1"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "TITLE2" VALUE
= " ">
<INPUT TYPE = "HIDDEN" NAME = "FIRST_NAME2"
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_ADDRESS"
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="ma**@address.com">
<INPUT TYPE="HIDDEN" NAME="SS_SUBJECT" VALUE="Membership Credit Card
Secure Order">
<INPUT TYPE="HIDDEN" NAME="SS_NEXTPAGE"
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="CardHolder" 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="CreditCard">
<option value=" ">
<option>VISA
<option>Mastercard
</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><INPUT TYPE = "Reset"></td>
</tr>
</table>
</FORM>
<BR>
<BR>
</HTML>

Jul 23 '05 #1
10 4053
dries wrote:
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.getYear() + 1900;
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <=
thisyear))


thisdate = new Date();
thisdate.setMonth(thisdate.getMonth()+1)
thisyear = thisdate.getFullYear()
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <= thisyear))

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

Mick
Jul 23 '05 #2
Mick White wrote:

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

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

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)
Jul 23 '05 #3
JRS: In article <6l********************************@4ax.com>, dated
Fri, 13 Aug 2004 15:48:35, seen in news:comp.lang.javascript, dries
<dr***@driesbessels.removebeforeuse.com> posted :

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.
Your friend is not competent enough to be entrusted with financial
software.
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.
I think you mean that it apparently expires one month early.

<script language="JAVASCRIPT">
Deprecated.
var CCname = document.Final.CardHolder.value;
var CCmonth =
document.Final.ExpMonth.options[document.Final.ExpMonth.selectedIndex].value;
var CCyear =
document.Final.ExpYear.options[document.Final.ExpYear.selectedIndex].value;
var CCval = document.Final.CCNo.value;
var CCtype =
document.Final.CreditCard.options[document.Final.CreditCard.selectedIndex].value
;
Those are strings. Use ... = + ... to get Numbers.
var failed = false;
// check if credit card name has been entered
if (failed == false)
Should be if (!failed) // throughout.

//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
Gives wrong answer on some systems, AIUI. See via FAQ & sig.
thismonth = thisdate.getMonth();
Gives 0..11 - this the problem that you have seen. Add 1.

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

function _isinteger(test_string){
var i;
var non_nums = 0;
for (i = 1; i < test_string.length; i++){
if ((test_string.substring(i-1,i) < '0') ||
(test_string.substring(i-1,i) > '9'))
non_nums++;
}
if (non_nums == 0)
return true;
else
return false;
return non_nums == 0 // is simpler.
}
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.demon.co.uk/js-valid.htm>.

function CC_Validate(ccnumber){
var checksum = 0;
var i;
var digit;
var temp;
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.

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

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


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.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #4
Thanks for all the comments, I will relay them to the writer!
Brgds
Dries

Jul 23 '05 #5
Thanks for all the comments, I will relay them to the writer!
Brgds
Dries

Jul 23 '05 #6
On Fri, 13 Aug 2004 15:48:35 +0200, dries
<dr***@driesbessels.removebeforeuse.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.org/>.

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.
<HTML>
Valid HTML documents should contain a document type declaration. See
<URL:http://www.w3.org/TR/html401/struct/global.html#h-7.2>.
<HEAD><TITLE>Secure Credit Card Transaction</TITLE>
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.
</HEAD>
<BODY BGCOLOR="#FFFF00">
<script language="JAVASCRIPT">
The language attribute is deprecated. Furthermore, the required type
attribute makes it redundant. Change this to:

<script type="text/javascript">
<!--
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.
//This function validates entry credit card
information
function _vet(){
var thisyear;
var thismonth;
var thisdate;
var CCname = document.Final.CardHolder.value;
var CCmonth =
document.Final.ExpMonth.options[document.Final.ExpMonth.selectedIndex].value;
var CCyear =
document.Final.ExpYear.options[document.Final.ExpYear.selectedIndex].value;
var CCval = document.Final.CCNo.value;
var CCtype =
document.Final.CreditCard.options[document.Final.CreditCard.selectedIndex].value;
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...
var failed = false;
// check if credit card name has been entered
if (failed == false)
if(!failed) // if not failed

[snip]
//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
Date.getFullYear() returns a four-digit year between 1000 and 9999

thisyear = thisdate.getFullYear();
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <=
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]
if (failed == false)
document.Final.submit();
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="return validate(this)">
<!-- Rest of form -->
<input type="submit" value="Submit">
</form>
function _strip_spaces(_ipstr)
[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".
function _isinteger(test_string){
[snip]

Again, a regular expression would be better:

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

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_string);
if (non_nums == 0)
return true;
else
return false;
return (non_nums == 0);
}

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

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

for (i = 0; i < cclength; i++){
digit = parseInt(ccnumber.charAt(i));
If the string has already been validated as containing numbers only, it
would be more efficient to use:

digit = +ccnumber.charAt(i);

In any case, you shouldn't call parseInt() with only a single arguement;
always specify the base.
if ((i % 2) == 0){
digit *= 2;
if (digit > 9)
digit = parseInt(digit / 10) + parseInt(digit
% 10);
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.
}
checksum += digit;
}

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

[snip]
<INPUT TYPE="HIDDEN" NAME="SS_TO" VALUE="ma**@address.com">
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]
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
This is invalid HTML. Table rows are required to contain at least one
table cell (TD) or header (TH).

[snip]
<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>
What exactly is the point in specifying the years above? If used, they
will always evaluate to false.

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


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.pwp.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
Jul 23 '05 #7
JRS: In article <opscqgitemx13kvk@atlantis>, dated Sat, 14 Aug 2004
17:35:15, seen in news:comp.lang.javascript, Michael Winter <M.Winter@bl
ueyonder.co.invalid> posted :
On Fri, 13 Aug 2004 15:48:35 +0200, dries
<dr***@driesbessels.removebeforeuse.com> wrote: Date.getFullYear() returns a four-digit year between 1000 and 9999
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.

In any case, you shouldn't call parseInt() with only a single arguement;
always specify the base.
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.

It should also be noted that arithmetic is not exact in JavaScript, and
these operations should be rounded.


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.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #8
On Sun, 15 Aug 2004 13:29:11 +0100, Dr John Stockton
<sp**@merlyn.demon.co.uk> wrote:

[range of Date.getFullYear()]
That is so. OTOH it may be misleading (are you thinking ofVBscript,
though the lower limit there is 100?);
No. I took that from the JavaScript reference as it was hand at the time.
I believe the range to be -271821-04-21 to +275760-09-13; 10^8 daysfrom
the start of 1970 GMT.
I calculated a different value, but Opera returns the values you state
above. In any event, its of that order of magnitude.
Most browsers in current use should have getFullYear.
It was added to JavaScript in v1.3. I wish the ECMAScript specification
noted what was added, when.

[parseInt()]
In this case, IIRC, the first argument is a single digit string; 1..9
will be taken as decimal, and 0 as octal, AIUI.
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...are 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".
Granted, parseInt is not needed. It would probably be faster to use
charCodeAt and subtract 48.


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

[snip]

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail
Jul 23 '05 #9
JRS: In article <opscsda1y0x13kvk@atlantis>, dated Sun, 15 Aug 2004
18:20:35, seen in news:comp.lang.javascript, Michael Winter <M.Winter@bl
ueyonder.co.invalid> posted :

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


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...are 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.

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.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #10
On Mon, 16 Aug 2004 11:56:15 +0100, Dr John Stockton
<sp**@merlyn.demon.co.uk> wrote:
JRS: In article <opscsda1y0x13kvk@atlantis>, dated Sun, 15 Aug 2004
18:20:35, seen in news:comp.lang.javascript, Michael Winter
<M.******@blueyonder.co.invalid> posted :
[snip]
According to ECMA-262, the absence of a second argument, or 0, defaults
to base-10.


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]
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.
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]
ECMA evidently does not like leading-zero-means-octal, but cannot
disregard precedent.


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
Jul 23 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: kaptain kernel | last post by:
I'm implementing a simple credit card number check on my website, in order to trap user errors. it doesn't validate with the bank, but validates against certain known rules (e.g. Amex always begins...
7
by: gj | last post by:
I have an application in Access 97 I will be rewriting in the latest version of Access in 6 months. In the meantime, does anyone know of an ActiveX control I can add into an Access 97 form to...
6
by: Grant | last post by:
Does any one know how to check the algorithm of the credit card number that was entered in the text box? I want to be able to make sure the users enter correct credit card number since we will...
4
by: Michelle A. | last post by:
I have a form that takes in a credit card number, just a series of numbers 1234123412341234. When they get to the "Review" page and display all the information a user has entered, I would like the...
7
by: Sandy | last post by:
I need a credit card validator. Is there reliable code already written that anyone knows of? I have come across a few things; i.e. the Luhn-10 algorithm, but don't know if that still applies or...
3
by: tshad | last post by:
I am looking to connect my asp.net pages to a credit card processor, such as ICVerify. I used to be able to read and write to a text file: credit card authorizations, cancelations, get responses...
1
by: Bill D'Innocenzo | last post by:
There are many functions available that implement credit card identification and number validation -- meaning you can decide, based on the number, if a card is a MasterCard or Visa and if the...
1
by: securedcardss | last post by:
http://card.2youtop.info secured credit card card credit instant secured card cash credit secured card
4
code green
by: code green | last post by:
Data Protection etc.... shouldn't be there. How do I find credit card numbers buried amongst any length of text. Googling finds credit card validation claims, which are too complicated. I need...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.