|
Message-ID: <20110518232930.GA5976@openwall.com> Date: Thu, 19 May 2011 03:29:30 +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 Wed, May 18, 2011 at 02:44:07PM -0400, brad@...ystems.com wrote: > I do not believe that IINs are public data. They appear to be semi-public. Here's a database for sale, for $500: http://www.binbase.com/search.html (with limited online lookups as a demo). Also, this Wikipedia page has some IIN ranges: http://en.wikipedia.org/wiki/Bank_card_number A few of them include the first 6 digits. 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. It may be faster to generate the all-digit strings with an external mode on its own, adjusting the Luhn digit as necessary. [List.External:Append_Luhn_Digit] int map1[0x100], map2[0x1fff]; void init() { int i; map1[0] = ~0x7fffffff; i = 1; while (i < 0x100) map1[i++] = 0x01000000; 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 (((o | e) & 0x7fffffff) >= 0x01000000) return; // Not all-digit, leave unmodified word[i--] = 0; word[i] = map2[(e & 0xfff) + (o >> 12)]; return; } if (((o | e) & 0x7fffffff) >= 0x01000000) return; // Not all-digit, leave unmodified word[i--] = 0; word[i] = map2[(o & 0xfff) + (e >> 12)]; } 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) i++; sum[i & 1] &= 0x7fffffff; if ((sum[0] | sum[1]) >= 0x01000000) return; // Not all-digit, leave unmodified word[i] = map2[(sum[i & 1] & 0xfff) + (sum[~i & 1] >> 12)]; word[++i] = 0; } These use the same trick: compute the length and four sums in parallel (in two SIMD'ish variables or array elements). Then whether the length is even or odd determines which two of the four sums are actually used. Checks for non-digits and for NUL are packed into the SIMD'ish values as well. So it's 1 bit for NUL, 7 bits for counting non-digits, 12 bits for one partial sum, 12 bits for the other. 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.