/* cccheck.c - basic example of how a credit card works. */ /* Jon Mayo - January 2007 - PUBLIC DOMAIN - No copyright claimed */ #include #include #include #include /* http://www.webopedia.com/TERM/L/Luhn_formula.html * http://www.merriampark.com/anatomycc.htm * http://en.wikipedia.org/wiki/ISO_3166-1_numeric */ /* [MII - Major Industry Identifier] * 0 ISO/TC68 or other industry assignment * 1 airlines * 2 airlines and other industry assignment * 3 travel and entertainment * 4 banking and financial * 5 banking and financial * 6 merchandizing and banking * 7 petroleum * 8 telecommunications and other industry assignment * 9 national assignment * * [Issuer] - combine MII + 5 digits * 300xxx-305xxx - diner's club/carte blanche * 34xxxx-37xxxx - american express * 4xxxxx - VISA * 51xxxx-55xxxx - mastercard * 6011xx - discover * 9004xx * 9004xx - national issuer: Afghanistan * 9008xx - national issuer: Albania * 9010xx - national issuer: Antarctica * 9012xx - national issuer: Algeria * 9016xx - national issuer: American Samoa * 9020xx - national issuer: Andorra * 9024xx - national issuer: Angola * 9028xx - national issuer: Antigua and Barbuda * 9031xx - national issuer: Azerbaijan * 9032xx - national issuer: Argentina * 9036xx - national issuer: Australia * 9040xx - national issuer: Austria * 9044xx - national issuer: Bahamas * 9048xx - national issuer: Bahrain * 9050xx - national issuer: Bangladesh * 9051xx - national issuer: Armenia * 9052xx - national issuer: Barbados * 9056xx - national issuer: Belgium * 9060xx - national issuer: Bermuda * 9064xx - national issuer: Bhutan * 9068xx - national issuer: Bolivia * 9070xx - national issuer: Bosnia and Herzegovina * 9072xx - national issuer: Botswana * 9074xx - national issuer: Bouvet Island * 9076xx - national issuer: Brazil * 9084xx - national issuer: Belize * 9086xx - national issuer: British Indian Ocean Territory * 9090xx - national issuer: Solomon Islands * 9092xx - national issuer: Virgin Islands, British * 9096xx - national issuer: Brunei Darussalam * 9100xx - national issuer: Bulgaria * 9104xx - national issuer: Myanmar * 9108xx - national issuer: Burundi * 9112xx - national issuer: Belarus * 9116xx - national issuer: Cambodia * 9120xx - national issuer: Cameroon * 9124xx - national issuer: Canada * 9132xx - national issuer: Cape Verde * 9136xx - national issuer: Cayman Islands * 9140xx - national issuer: Central African Republic * 9144xx - national issuer: Sri Lanka * 9148xx - national issuer: Chad * 9152xx - national issuer: Chile * 9156xx - national issuer: China * 9158xx - national issuer: Taiwan, Province of China * 9162xx - national issuer: Christmas Island * 9166xx - national issuer: Cocos (Keeling) Islands * 9170xx - national issuer: Colombia * 9174xx - national issuer: Comoros * 9175xx - national issuer: Mayotte * 9178xx - national issuer: Congo * 9180xx - national issuer: Congo, the Democratic Republic of the * 9184xx - national issuer: Cook Islands * 9188xx - national issuer: Costa Rica * 9191xx - national issuer: Croatia * 9192xx - national issuer: Cuba * 9196xx - national issuer: Cyprus * 9203xx - national issuer: Czech Republic * 9204xx - national issuer: Benin * 9208xx - national issuer: Denmark * 9212xx - national issuer: Dominica * 9214xx - national issuer: Dominican Republic * 9218xx - national issuer: Ecuador * 9222xx - national issuer: El Salvador * 9226xx - national issuer: Equatorial Guinea * 9231xx - national issuer: Ethiopia * 9232xx - national issuer: Eritrea * 9233xx - national issuer: Estonia * 9234xx - national issuer: Faroe Islands * 9238xx - national issuer: Falkland Islands (Malvinas) * 9239xx - national issuer: South Georgia and the South Sandwich Islands * 9242xx - national issuer: Fiji * 9246xx - national issuer: Finland * 9248xx - national issuer: Åland Islands * 9250xx - national issuer: France * 9254xx - national issuer: French Guiana * 9258xx - national issuer: French Polynesia * 9260xx - national issuer: French Southern Territories * 9262xx - national issuer: Djibouti * 9266xx - national issuer: Gabon * 9268xx - national issuer: Georgia * 9270xx - national issuer: Gambia * 9275xx - national issuer: Palestinian Territory, Occupied * 9276xx - national issuer: Germany * 9288xx - national issuer: Ghana * 9292xx - national issuer: Gibraltar * 9296xx - national issuer: Kiribati * 9300xx - national issuer: Greece * 9304xx - national issuer: Greenland * 9308xx - national issuer: Grenada * 9312xx - national issuer: Guadeloupe * 9316xx - national issuer: Guam * 9320xx - national issuer: Guatemala * 9324xx - national issuer: Guinea * 9328xx - national issuer: Guyana * 9332xx - national issuer: Haiti * 9334xx - national issuer: Heard Island and McDonald Islands * 9336xx - national issuer: Holy See (Vatican City State) * 9340xx - national issuer: Honduras * 9344xx - national issuer: Hong Kong * 9348xx - national issuer: Hungary * 9352xx - national issuer: Iceland * 9356xx - national issuer: India * 9360xx - national issuer: Indonesia * 9364xx - national issuer: Iran, Islamic Republic of * 9368xx - national issuer: Iraq * 9372xx - national issuer: Ireland * 9376xx - national issuer: Israel * 9380xx - national issuer: Italy * 9384xx - national issuer: Côte d'Ivoire * 9388xx - national issuer: Jamaica * 9392xx - national issuer: Japan * 9398xx - national issuer: Kazakhstan * 9400xx - national issuer: Jordan * 9404xx - national issuer: Kenya * 9408xx - national issuer: Korea, Democratic People's Republic of * 9410xx - national issuer: Korea, Republic of * 9414xx - national issuer: Kuwait * 9417xx - national issuer: Kyrgyzstan * 9418xx - national issuer: Lao People's Democratic Republic * 9422xx - national issuer: Lebanon * 9426xx - national issuer: Lesotho * 9428xx - national issuer: Latvia * 9430xx - national issuer: Liberia * 9434xx - national issuer: Libyan Arab Jamahiriya * 9438xx - national issuer: Liechtenstein * 9440xx - national issuer: Lithuania * 9442xx - national issuer: Luxembourg * 9446xx - national issuer: Macao * 9450xx - national issuer: Madagascar * 9454xx - national issuer: Malawi * 9458xx - national issuer: Malaysia * 9462xx - national issuer: Maldives * 9466xx - national issuer: Mali * 9470xx - national issuer: Malta * 9474xx - national issuer: Martinique * 9478xx - national issuer: Mauritania * 9480xx - national issuer: Mauritius * 9484xx - national issuer: Mexico * 9492xx - national issuer: Monaco * 9496xx - national issuer: Mongolia * 9498xx - national issuer: Moldova, Republic of * 9499xx - national issuer: Montenegro * 9500xx - national issuer: Montserrat * 9504xx - national issuer: Morocco * 9508xx - national issuer: Mozambique * 9512xx - national issuer: Oman * 9516xx - national issuer: Namibia * 9520xx - national issuer: Nauru * 9524xx - national issuer: Nepal * 9528xx - national issuer: Netherlands * 9530xx - national issuer: Netherlands Antilles * 9533xx - national issuer: Aruba * 9540xx - national issuer: New Caledonia * 9548xx - national issuer: Vanuatu * 9554xx - national issuer: New Zealand * 9558xx - national issuer: Nicaragua * 9562xx - national issuer: Niger * 9566xx - national issuer: Nigeria * 9570xx - national issuer: Niue * 9574xx - national issuer: Norfolk Island * 9578xx - national issuer: Norway * 9580xx - national issuer: Northern Mariana Islands * 9581xx - national issuer: United States Minor Outlying Islands * 9583xx - national issuer: Micronesia, Federated States of * 9584xx - national issuer: Marshall Islands * 9585xx - national issuer: Palau * 9586xx - national issuer: Pakistan * 9591xx - national issuer: Panama * 9598xx - national issuer: Papua New Guinea * 9600xx - national issuer: Paraguay * 9604xx - national issuer: Peru * 9608xx - national issuer: Philippines * 9612xx - national issuer: Pitcairn * 9616xx - national issuer: Poland * 9620xx - national issuer: Portugal * 9624xx - national issuer: Guinea-Bissau * 9626xx - national issuer: Timor-Leste * 9630xx - national issuer: Puerto Rico * 9634xx - national issuer: Qatar * 9638xx - national issuer: Réunion * 9642xx - national issuer: Romania * 9643xx - national issuer: Russian Federation * 9646xx - national issuer: Rwanda * 9654xx - national issuer: Saint Helena * 9659xx - national issuer: Saint Kitts and Nevis * 9660xx - national issuer: Anguilla * 9662xx - national issuer: Saint Lucia * 9666xx - national issuer: Saint Pierre and Miquelon * 9670xx - national issuer: Saint Vincent and the Grenadines * 9674xx - national issuer: San Marino * 9678xx - national issuer: Sao Tome and Principe * 9682xx - national issuer: Saudi Arabia * 9686xx - national issuer: Senegal * 9688xx - national issuer: Serbia * 9690xx - national issuer: Seychelles * 9694xx - national issuer: Sierra Leone * 9702xx - national issuer: Singapore * 9703xx - national issuer: Slovakia * 9704xx - national issuer: Viet Nam * 9705xx - national issuer: Slovenia * 9706xx - national issuer: Somalia * 9710xx - national issuer: South Africa * 9716xx - national issuer: Zimbabwe * 9724xx - national issuer: Spain * 9732xx - national issuer: Western Sahara * 9736xx - national issuer: Sudan * 9740xx - national issuer: Suriname * 9744xx - national issuer: Svalbard and Jan Mayen * 9748xx - national issuer: Swaziland * 9752xx - national issuer: Sweden * 9756xx - national issuer: Switzerland * 9760xx - national issuer: Syrian Arab Republic * 9762xx - national issuer: Tajikistan * 9764xx - national issuer: Thailand * 9768xx - national issuer: Togo * 9772xx - national issuer: Tokelau * 9776xx - national issuer: Tonga * 9780xx - national issuer: Trinidad and Tobago * 9784xx - national issuer: United Arab Emirates * 9788xx - national issuer: Tunisia * 9792xx - national issuer: Turkey * 9795xx - national issuer: Turkmenistan * 9796xx - national issuer: Turks and Caicos Islands * 9798xx - national issuer: Tuvalu * 9800xx - national issuer: Uganda * 9804xx - national issuer: Ukraine * 9807xx - national issuer: Macedonia, the former Yugoslav Republic of * 9818xx - national issuer: Egypt * 9826xx - national issuer: United Kingdom * 9831xx - national issuer: Guernsey * 9832xx - national issuer: Jersey * 9833xx - national issuer: Isle of Man * 9834xx - national issuer: Tanzania, United Republic of * 9840xx - national issuer: United States * 9850xx - national issuer: Virgin Islands, U.S. * 9854xx - national issuer: Burkina Faso * 9858xx - national issuer: Uruguay * 9860xx - national issuer: Uzbekistan * 9862xx - national issuer: Venezuela * 9876xx - national issuer: Wallis and Futuna * 9882xx - national issuer: Samoa * 9887xx - national issuer: Yemen * 9894xx - national issuer: Zambia */ typedef unsigned long long cc_t; /* converts a string to a compact internal form. */ int cc_parse(const char *str, cc_t *cn) { cc_t tmp; unsigned len; len=strlen(str); tmp=0; while(len--) { if(isdigit(str[len])) { } else if(!isspace(str[len])) { fprintf(stderr, "%s:%u:Could not parse number\n", __FILE__, __LINE__); return 0; } } *cn=tmp; return 1; } /* expand the internal for to a decimal representation. * if buf is 0 then return the value in a static buffer. */ const char *cc_expand(cc_t cn, char *buf, size_t len) { static char buf_static[20]; char *dest; int curr; if(buf) { dest=buf; } else { dest=buf_static; len=sizeof buf_static; } if(cn>999999999999999ll && cn<10000000000000000ll) { /* format 16-digit cards nicely */ snprintf(dest, len, "%04u %04u %04u %04u", (unsigned)((cn/1000000000000ll)%10000), (unsigned)((cn/100000000l)%10000), (unsigned)((cn/10000)%10000), (unsigned)(cn%10000)); } else { snprintf(dest, len, "%lld", cn); } return dest; } /* check if the number is valid */ int cc_check(cc_t cn) { unsigned tally, tmp, i; tally=0; for(i=0;cn && i<20;i+=2) { /* max is really 19 digits, but stop at 20. */ tally+=(cn%10); cn/=10; tmp=2*(cn%10); cn/=10; tally+=tmp%10; tally+=(tmp/10); } return (tally%10) == 0; } int cc_decode(cc_t cn, unsigned *mii, unsigned *issuer, unsigned long long *account, unsigned *chkdigit) { /* TODO: implement this */ return 0; } /* TODO: finish this */ cc_t cc_makecheck(cc_t cn) { unsigned tally, tmp, i; cc_t ret; tally=0; for(i=0;cn && i<20;i+=2) { /* max is really 19 digits, but stop at 20. */ tally+=(cn%10); cn/=10; tmp=2*(cn%10); cn/=10; tally+=tmp%10; tally+=(tmp/10); } return ret; } /* generate random 16-digit number */ int cc_generate(cc_t *cn, unsigned issuer, unsigned long long account) { if(!cn) return 0; *cn=0; if(issuer>=1000000l) return 0; *cn=cc_makecheck(issuer*10000000000000000ll+account); return 1; } /* create a small random credit card number */ cc_t cc_random(void) { cc_t cn; cc_generate(&cn, rand()%1000000l, rand() * 31337); return cn; } #if 1 #include static void test(void) { const cc_t test[] = { /* some test values to try */ 4408041234567893ll, 4417123456789113ll, }; int i; for(i=0;i