[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
```Date: Mon, 23 May 2011 05:31:34 +0400
From: Solar Designer <solar@...nwall.com>
To: john-users@...ts.openwall.com
Subject: Re: Help with 14 - 16 digit CC's stored in MD5 hash

On Thu, May 19, 2011 at 03:29:30AM +0400, Solar Designer wrote:
> Here's an external mode filter() that will add the Luhn algorithm digit
> to arbitrary all-digit strings.  It's optimized for speed, not for size
> nor simplicity, yet is still not as fast as I would have liked it to be.
...
> Here's a slightly simpler but slower revision of the filter() function:
>
> void filter()
> {
> 	int i, sum[2];
>
> 	i = sum[0] = sum[1] = 0;
> 	while ((sum[i & 1] += map1[word[i]]) > 0)

There's a bug in this "simpler but slower revision": the check above
should have been for ">= 0", not "> 0".  This affected strings starting
with "0".

Anyway, below is a slightly faster revision.  This one doesn't bother
counting non-digits; instead, it exits the loop on first non-digit seen.

[List.External:AppendLuhn]
int map1[0x100], map2[0x1fff];

void init()
{
int i;

map1[0] = ~0x7fffffff;
i = 1;
while (i < 0x100)
map1[i++] = ~0x7effffff;
i = -1;
while (++i < 10)
map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12);
i = -1;
while (++i < 0x1fff) {
if (i % 10)
map2[i] = '9' + 1 - i % 10;
else
map2[i] = '0';
}
}

void filter()
{
int i, o, e;

i = o = e = 0;
while ((o += map1[word[i++]]) >= 0) {
if ((e += map1[word[i++]]) >= 0)
continue;
if (e & 0x01000000)
return; // Not all-digit, leave unmodified
word[i--] = 0;
word[i] = map2[(e & 0xfff) + (o >> 12)];
return;
}
if (o & 0x01000000)
return; // Not all-digit, leave unmodified
word[i--] = 0;
word[i] = map2[(o & 0xfff) + (e >> 12)];
}

Alexander
```

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.