Follow @Openwall on Twitter for new release announcements and other news
[<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

Powered by blists - more mailing lists

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