Looking for a certain regexp

D

Dale Henderson

DH> In fact the first step of the Luhn test can be done with:

DH> $cc=1234567890123456
Make that $cc="1234567890123456";
Sorry I didn't test with such a large number.

DH> $cc=~s/(\d)(\d)/(x==9?9:($1*2)%9).$2/eg;

DH> This assumes the length of $cc is even (for odd length a
DH> different replacement is needed) and doubles the odd numbered
DH> digits with appropriate modifications (add the digits of 2
DH> digit numbers).

DH> For the next step putting a plus between the digits and
DH> using an eval would work.
 
D

Dale Henderson

PG> Dale Henderson said:
Dale Henderson wrote:

PG> Why? Simple logic indicates using regexes to run a
PG> mathematical formula and perform a modulus ten test, is
PG> realistically impossible.

I think you mean intuition or experience. Logic has nothing to do
with it.

Many things that are counter-intuitive are true.

Would you think you find integer solutions to

12x + 15y + 16z = 281 with a Regular Expression?

(You can a solution is in Chapter 6 Section 16 of the Perl
Cookbook 1st edition. (You know I really miss Tom Christiansen's
posts.))


PG> By the time you string together a slew of regex kludges, and
PG> still cannot _reliably_ validate a credit card number, you
PG> will think,

PG> "This is impossible."

Simply because you *think* it is impossible does not make it so.

PG> Perhaps you can do this, but by the time you perfect a regex
PG> method, you will wish you hadn't wasted your time on such a
PG> silly project.

I will?!

Such projects may not lead to practical solutions but often lead
to deeper understandings of the issues involved (i.e. Regular
Expressions) and are therefore fruitful simply because you
*learn* something.

PG> Otherwords, you don't want to tackle this notion of using
PG> regexes for validating credit card numbers. Perhaps you are
PG> concerned you cannot do this?

In other words, I never made a claim that required proof.

PG> Ok, you are girl who displays all the classic signs of
PG> Terminal Testosterone Poisoning.

I never said I was a "girl" either. You should start reading
what I type and stop making too many inferences.

The fact of the matter is: you do not know my gender. And I have
no intention of telling you what it is. For my gender is
irrelevant to the discussion at hand as is yours.



PG> Purl Gurl
 
A

Anno Siegel

Dale Henderson said:
[...]

PG> You cannot use a regex for validating credit card numbers.

I wouldn't be so quick to say what can't be done with a regular
expression. Regular expressions (especially Perl regular
expressions) are very powerful and can even be
[...]

In fact the first step of the Luhn test can be done with:

$cc=1234567890123456

$cc=~s/(\d)(\d)/(x==9?9:($1*2)%9).$2/eg;
This assumes the length of $cc is even (for odd length a
different replacement is needed) and doubles the odd numbered
digits with appropriate modifications (add the digits of 2 digit
numbers).

Careful there. ($1*2)%9 is wrong for $1 == 9. It gives 0, but
the total of the digits in 2*9 is 9.

Anno
 
A

Anno Siegel

Dale Henderson said:
[...]

PG> You cannot use a regex for validating credit card numbers.

I wouldn't be so quick to say what can't be done with a regular
expression. Regular expressions (especially Perl regular
expressions) are very powerful and can even be
[...]

In fact the first step of the Luhn test can be done with:

$cc=1234567890123456

$cc=~s/(\d)(\d)/(x==9?9:($1*2)%9).$2/eg;
This assumes the length of $cc is even (for odd length a
different replacement is needed) and doubles the odd numbered
digits with appropriate modifications (add the digits of 2 digit
numbers).

Careful there. ($1*2)%9 is wrong for $1 == 9. It gives 0, but
the total of the digits in 2*9 is 9.

( 0, 2, 4, 6, 8, 1, 3, 5, 7, 9)[ $1]
or
2*($1 % 5) + int( $1/5)

are possibilities.

Anno
 
G

GreenLight

Purl Gurl said:
In that sample above, you employ more the two dozen
excess characters. Many others here do the same.
Many in all newsgroups do the same. Total bandwidth
wasted by unwarranted "look-at-me" quoting, is
probably many gigabytes per day, possibly in the
range of terabytes per day.

How ironic that, after dozens of off-topic posts about the "crimes"
of CLPM, consuming "possibly" many megabytes, that you would start
harping on someone's quoting style as "wasting bandwidth".
Not something I complain about but usage of unacceptable
quoting methods is growing at a fast pace in this group.

Kinda selfish to waste internet bandwidth simply
to be cool, yes?

Kinda selfish to waste internet bandwidth by harassing an entire
newsgroup with off-topic posts detailing how many times your website
was hit.
 
D

Dale Henderson

AS> [...]

PG> You cannot use a regex for validating credit card numbers.
AS> [...]

AS> Careful there. ($1*2)%9 is wrong for $1 == 9. It gives 0,
AS> but the total of the digits in 2*9 is 9.

There's a typo there I just noticed it should read
($1==9?9:($1*2)%9) not (x==9?9:($1*2)%9).

The ?: takes care of the special case.

AS> ( 0, 2, 4, 6, 8, 1, 3, 5, 7, 9)[ $1] or 2*($1 % 5) + int(
AS> $1/5)

AS> are possibilities.

AS> Anno
 
D

Dale Henderson

Abigail> Checksums *can* be checked with a regexp. Regexes for
Abigail> certain credit cards are on my todo list for
Abigail> Regexp::Common. Now, if only I could find the URLs with
Abigail> the checksum formulas....

I'd be very interested in seeing a regex that checked a checksum.

I've been playing with this for a while and come up with regex
based replacement that works:

#!/usr/bin/perl

use strict;
use warnings;

sub luhn{
# this routine assumes the length of the card number is even.
# it can be easily modified to odd length numbers.

my $cc=shift;
$cc=~s/(\d)(\d)/($1?1x$1:0).($2?2x$2:0)/ge;
$cc=~s/1/11/g;
$cc=~s/1{10}/1/g;
$cc=~s/0//g;
return !(length($cc)%10);

#or
# return length($cc)=~/0$/;
#or
# $cc=~s/2/1/g;
# return $cc=~/^(1{10})+$/;
}

my $cc;

foreach $cc qw(1234567890123456 1234567890123452){
print $cc;
if(luhn($cc)){
print " -- Good\n";
}else{
print " -- Bad\n";
}
}

camel$ luhn.pl

1234567890123456 -- Bad
1234567890123452 -- Good

However, I wonder if could be done more along the lines of

if ($cc=~/$re/){
print " -- Good\n";"
}

etc.
 
D

Dale Henderson

PG> foreach $cc qw(0000000000000000)

Gives

0000000000000000 -- Good

which is correct.

There is a bug in one of the alternative returns.
It should read:

return $cc=~/^(1{10})*$/

not

return $cc=~/^(1{10})+/

PG> Purl Gurl
 
D

Dale Henderson

PG> foreach $cc qw(0)

From the code:

# this routine assumes the length of the card number is even.
# it can be easily modified to odd length numbers.

i.e. it doesn't work with strings of odd length.

PG> Purl Gurl
 
A

Anno Siegel

Dale Henderson said:
Abigail> Checksums *can* be checked with a regexp. Regexes for
Abigail> certain credit cards are on my todo list for
Abigail> Regexp::Common. Now, if only I could find the URLs with
Abigail> the checksum formulas....

I'd be very interested in seeing a regex that checked a checksum.

I've been playing with this for a while and come up with regex
based replacement that works:

#!/usr/bin/perl

use strict;
use warnings;

sub luhn{
# this routine assumes the length of the card number is even.
# it can be easily modified to odd length numbers.

my $cc=shift;
$cc=~s/(\d)(\d)/($1?1x$1:0).($2?2x$2:0)/ge;
$cc=~s/1/11/g;
$cc=~s/1{10}/1/g;
$cc=~s/0//g;
return !(length($cc)%10);

#or
# return length($cc)=~/0$/;
#or
# $cc=~s/2/1/g;
# return $cc=~/^(1{10})+$/;
}

my $cc;

foreach $cc qw(1234567890123456 1234567890123452){
print $cc;
if(luhn($cc)){
print " -- Good\n";
}else{
print " -- Bad\n";
}
}

camel$ luhn.pl

1234567890123456 -- Bad
1234567890123452 -- Good

However, I wonder if could be done more along the lines of

if ($cc=~/$re/){
print " -- Good\n";"
}

Using the (?{ code }) and (??{ code }) constructs, it can.

In particular, we can use (?{ code }) to build up the checksum in
a global variable. Summing only the first 15 digits, we can predict
the 16th and use (?{{ code }) to insert it as the expected match.

our ( $sum, $odd);
my $re = qr/
(?: # repeat the following
(\d) # match and capture a digit
(?{ # increment $sum accordingly
$sum += ( $odd ? $1 : ( $1 == 9) ? 9 : (2*$1) % 9);
$odd = not $odd;
})
){15} # repeat for 15 digits
(??{ # predict and match 16th digit
-$sum % 10;
})
/x;

for ( qw( 1234567890123456 1234567890123452) ) {
my $verdict = /$re/ ? 'Good' : 'Bad';
print "$_ -- $verdict\n";
}


Of course, this still isn't a pure regex solution, it uses non-regex
Perl code.

Anno
 
D

Dale Henderson

AS> Using the (?{ code }) and (??{ code }) constructs, it can.

AS> In particular, we can use (?{ code }) to build up the checksum
AS> in a global variable. Summing only the first 15 digits, we
AS> can predict the 16th and use (?{{ code }) to insert it as the
AS> expected match.

AS> our ( $sum, $odd);

AS> my $re = qr/
AS> (?: # repeat the following
AS> (\d) # match and capture a digit
AS> (?{ # increment $sum accordingly
AS> $sum += ( $odd ? $1 : ( $1 == 9) ? 9 : (2*$1)% 9);
AS> $odd = not $odd;
AS> })
AS> ){15} # repeat for 15 digits
AS> (??{ # predict and match 16th digit
AS> -$sum % 10;
AS> })
AS> /x;

AS> for ( qw( 1234567890123456 1234567890123452) ) {
AS> my $verdict = /$re/ ? 'Good' : 'Bad';
AS> print "$_ -- $verdict\n";
AS> }


AS> Of course, this still isn't a pure regex solution, it uses
AS> non-regex Perl code.

Perhaps not but this is still worthy of study which is the main
point of this exercise. I doubt that the regex solutions are very
efficient.

(Isn't that my mod 9 trick up there? :)

The ?{ code } and ??{ code } seem vaguely familiar. I couldn't
find anything about them in Camel 2 or "Mastering Regular
Expressions" (Owl) 1. So I read man page for perlre and found this
warning:

WARNING: This extended regular expression fea-
ture is considered highly experimental, and may
be changed or deleted without notice.

Since I'm running a fairly old version of perl (5.6.1), I wonder
if this warning is still in effect.

AS> Anno
 
J

Jeff 'japhy' Pinyan

The ?{ code } and ??{ code } seem vaguely familiar. I couldn't
find anything about them in Camel 2 or "Mastering Regular
Expressions" (Owl) 1. So I read man page for perlre and found this
warning:

WARNING: This extended regular expression fea-
ture is considered highly experimental, and may
be changed or deleted without notice.

Since I'm running a fairly old version of perl (5.6.1), I wonder
if this warning is still in effect.

They're still "highly experimental" in Perl 5.8.4, but they're here to
stay. Perl 6 will have them too.

In the mean time, you might want to check out an article I'm writing on
these two assertions:

http://japhy.perlmonk.org/articles/tpj/2004-summer.html
 
J

John Bokma

Purl Gurl wrote:

[ snip detective story ]
I suppose he is in a world of hurt now.

HURD? I bet he is a Purl Programmer. Must be. He clearly has a criminal
mind and such.
 
M

MichiganBob

Purl said:
In that sample above, you employ more the two dozen
excess characters. Many others here do the same.
Many in all newsgroups do the same. Total bandwidth
wasted by unwarranted "look-at-me" quoting, is
probably many gigabytes per day, possibly in the
range of terabytes per day.

Not something I complain about but usage of unacceptable
quoting methods is growing at a fast pace in this group.

Kinda selfish to waste internet bandwidth simply
to be cool, yes?

Pot...Kettle...Black.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top