/* spiderkiller: creates a list of bogus email addresses and writes them to standard output in html format. The purpose is to create web pages that clobber spammers' automated email address collection tools. (C) 1998 Peter Selinger. Version 1.3, 6/23/98 - 9/15/98. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* compile using: gcc spiderkiller.c -o spiderkiller */ #include #include #include #define mrand(range) (rand()%(range)) /* The following database holds a rough characterization of which pseudo-words are pronouncable in English; this makes for prettier spiderkiller pages, and may prevent future spammers from using a simple-minded method for filtering out "fakes". */ /* The eight tables below hold accumulative probabilities for groups of consonants, respectively vowels, to occur 0) as a word 1) at the end of a word 2) at the beginning of a word 3) inside a word */ struct key { char *syl; int x; }; /* consonants */ static struct key c0[] = {"by",19,"glyph",20,"my",41,"rhythms",42, "sky",44,}; static struct key c1[] = {"b",2,"bly",3,"bs",4,"c",9,"ch",36,"ck",42, "cks",44,"cky",45,"ct",46,"ctly",48,"cts",49,"d",184,"dd",185,"dn",189, "ds",193,"dsm",194,"dth",213,"dy",215,"f",330,"ff",333,"ffs",334,"fs",335, "ft",347,"fty",349,"g",351,"ggy",352,"gh",359,"ghly",362,"ght",410, "gn",445,"gs",449,"gy",450,"k",469,"ks",475,"l",554,"ld",565,"lf",568, "ll",602,"lls",603,"lly",611,"lp",613,"ls",618,"lsm",619,"lt",641, "lth",642,"lts",643,"ly",661,"m",718,"mb",720,"mg",739,"mmy",740,"ms",745, "my",746,"n",1010,"nch",1011,"ncy",1012,"nd",1136,"ndly",1137,"nds",1147, "ng",1254,"ngly",1256,"ngs",1266,"nks",1268,"nly",1278,"ns",1298, "nsm",1299,"nst",1300,"nt",1351,"nth",1352,"ntly",1355,"ntry",1358, "nts",1364,"ny",1377,"p",1403,"phy",1404,"ps",1406,"pt",1407,"r",1592, "rby",1594,"rch",1595,"rd",1604,"rds",1608,"rdy",1609,"rk",1615,"rks",1617, "rld",1619,"rly",1620,"rm",1622,"rmy",1624,"rn",1628,"rns",1629,"rry",1630, "rs",1662,"rsm",1664,"rst",1667,"rt",1675,"rth",1676,"rts",1679,"rty",1682, "ry",1695,"s",1935,"sh",1948,"sk",1949,"sly",1951,"sm",1962,"ss",1970, "ssm",1971,"st",2003,"stly",2004,"sts",2008,"sty",2009,"t",2185,"tc",2186, "tch",2188,"th",2216,"tl",2220,"tly",2221,"ts",2236,"ty",2253,"w",2279, "x",2291,"xt",2294,"xth",2295,"xty",2296,"z",2297,}; static struct key c2[] = {"b",149,"bgc",150,"bl",151,"br",157,"c",318, "ch",341,"cl",357,"cr",364,"d",432,"dr",439,"dysf",440,"f",556,"fl",560, "fr",596,"g",646,"gl",647,"gr",656,"h",792,"hr",810,"j",826,"k",829, "kn",834,"l",929,"ls",931,"m",1048,"mys",1050,"myst",1053,"n",1103, "p",1175,"ph",1212,"pl",1222,"pr",1236,"q",1248,"r",1312,"s",1460, "sc",1462,"sch",1475,"sh",1487,"sk",1488,"sl",1491,"sm",1498,"sp",1513, "spr",1514,"sq",1515,"st",1546,"str",1552,"styl",1553,"sw",1555, "sympt",1556,"syst",1558,"t",1808,"th",2132,"thr",2144,"tr",2156, "try",2157,"tw",2167,"v",2197,"w",2389,"wh",2426,"wr",2432,"x",2438, "xyl",2439,"y",2454,}; static struct key c3[] = {"b",20,"bbl",21,"bl",101,"br",103,"bsm",104, "c",181,"cc",184,"ch",197,"ck",205,"ckgr",206,"ckl",207,"ckn",208, "ckp",210,"cr",214,"ct",232,"ctr",236,"d",302,"dd",320,"ddl",321,"ddr",324, "dm",325,"dr",326,"f",344,"ff",353,"ft",366,"g",423,"gg",428,"gh",430, "ghb",432,"ghl",434,"ght",436,"gr",439,"gy",441,"h",443,"j",448,"k",486, "kf",487,"l",629,"lc",637,"ld",642,"ldr",650,"lk",652,"ll",678,"llp",695, "lm",697,"lph",698,"lr",699,"ls",709,"lt",729,"lv",731,"lw",733,"m",866, "mb",875,"mm",881,"mp",885,"mpl",895,"mpr",896,"mpt",897,"ms",898,"n",1013, "nc",1025,"nch",1026,"ncl",1027,"nct",1029,"nd",1060,"ndl",1061,"ndm",1062, "ndr",1065,"nf",1066,"ng",1090,"ngl",1098,"nh",1099,"nj",1100,"nk",1104, "nn",1110,"nr",1114,"ns",1130,"nsp",1131,"nst",1134,"nstr",1138,"nt",1209, "ntr",1215,"nv",1218,"nyw",1220,"nz",1221,"p",1238,"pc",1240,"pd",1241, "ph",1243,"pl",1256,"pp",1269,"ppr",1270,"pr",1272,"ps",1273,"pt",1311, "q",1322,"r",1493,"rc",1497,"rch",1500,"rd",1526,"rf",1532,"rg",1542, "rgr",1543,"rk",1551,"rm",1562,"rn",1583,"rnm",1587,"rp",1596,"rpr",1598, "rr",1612,"rs",1615,"rsd",1616,"rsh",1618,"rst",1621,"rt",1632, "rthq",1635,"rty",1636,"rv",1643,"rw",1644,"s",1709,"sc",1713,"scr",1714, "sd",1717,"sh",1722,"shl",1723,"sk",1727,"sl",1728,"sm",1729,"sp",1735, "sph",1736,"ss",1747,"st",1769,"str",1770,"t",1955,"tc",1956,"tf",1958, "tg",1959,"th",1968,"thl",1969,"tl",1972,"tm",1973,"tr",1974,"ts",1976, "tt",2000,"ttl",2006,"tz",2014,"v",2130,"w",2145,"wh",2146,"wl",2147, "wn",2149,"x",2161,"xp",2163,"xt",2167,"xtr",2169,"z",2178,}; /* vowels */ static struct key v0[] = {"a",120,"i",216,}; static struct key v1[] = {"a",50,"ay",95,"aya",99,"e",792,"ea",794, "ee",802,"ey",824,"i",827,"ia",834,"ie",835,"o",1042,"oo",1043,"u",1046, "ua",1061,"ue",1064,"uy",1066,}; static struct key v2[] = {"a",378,"aa",382,"ai",389,"au",391,"e",448, "ea",458,"eu",459,"eye",461,"i",670,"o",851,"ou",871,"u",909,}; static struct key v3[] = {"a",758,"ai",784,"au",798,"ay",811,"aya",813, "aye",815,"ayi",818,"ayou",819,"e",1664,"ea",1734,"eau",1736,"ee",1774, "ei",1810,"eo",1824,"eou",1825,"eu",1827,"ey",1828,"i",2505,"ia",2526, "ie",2558,"io",2617,"iou",2620,"o",3120,"oa",3124,"oe",3125,"oi",3129, "oo",3184,"ou",3282,"oye",3284,"u",3485,"ua",3527,"ue",3547,"ui",3564, "uyi",3566,}; int length[] = {44,2297,2454,2178,216,1066,909,3566,}; static struct key *a[]={c0,c1,c2,c3,v0,v1,v2,v3}; /** generates a random semi-syllable and stores it at acc; returns a pointer to the next unused character. vc=1 if vowel, =0 if consonant. lef=1 if at beginning of word, rig=1 if at end of word, else =0. */ char *gensyl(char *acc, int vc, int lef, int rig) { int flags=4*vc+3-lef-2*rig; /* in which table to look? */ int offs=mrand(length[flags]); /* select a syllable */ struct key *p=a[flags]; char *sp; while (p->x <= offs) /* and find it */ p++; sp=p->syl; /* copy */ while (*sp!='\0') { *acc=*sp; acc++; sp++; } return acc; } /** creates a random word of between min and max semi-syllables starting from acc[i]. Returns next unused index. */ int random_word(char *acc, int i, int min, int max) { int nsyl=min+mrand(max-min+1); int vc=mrand(2); int syl; char *cp=acc+i; for (syl=0; syl] [-k ] [-r ] [-x]\n" " -help: print this message\n" " -n: set maximal number of addresses created\n" " -k: set maximal size in kilobyte of the created code\n" " -r: set the random seed (an integer). Default is the current time.\n" " -x: print no html, just a list of addresses\n\n" "The purpose of this program is to create lists of bogus email\n" "addresses to clobber automated address collection tools, of the\n" "kind that spammers use. Feel free to put these on your web pages;\n" "the more, the merrier. (C) 1998 Peter Selinger. This is free\n" "software under the GNU General Public License.\n"); exit(1); } /** reads command line and writes to stdout */ main(int argc, char *argv[]) { int i, seed, max_number, do_html, len, debug; long max_filesize, filesize; char acc[200], *p; char *html_header= "SpiderKiller Spam Bait\n\n

SpiderKiller

\n\n" "The purpose of this file is to provide lots of bogus email addresses\n" "to clobber up automated email address collection tools of the kind\n" "that spammers use. It was created by the program \n" "\n" "spiderkiller. Feel free to download this C program and to\n" "create your own spiderkiller pages.

\n\n"; /* set defaults for command line options */ max_number=0; max_filesize=0; do_html=1; debug=0; seed=(int)time(NULL); // default random seed based on current time /* read command line */ ++argv, --argc; while (argc > 0) { p = *argv; ++argv, --argc; if (p[0] == '-') { /* '-x' must be an option */ p++; /* strip off the - */ switch(p[0]) { case 'h': /* -h help */ usage(); break; case 'd': /* -d debug */ debug++; break; case 'r': /* -r set random seed */ if (argc==0) { usage(); } seed=atoi(*argv); ++argv, --argc; break; case 'n': /* -n max number of addresses */ case 'a': /* -a for compatibility */ if (argc==0) { usage(); } max_number=atoi(*argv); ++argv, --argc; break; case 'k': /* -k max size in kilobytes */ if (argc==0) { usage(); } max_filesize=atoi(*argv) * 1024L; ++argv, --argc; break; case 'x': do_html=0; break; default: fprintf(stderr, "Illegal option: -%s\n", p); usage(); break; } } else { usage(); } } if (debug) { fprintf(stderr, "## seed: %d\n", seed); fprintf(stderr, "## max_number: %d\n", max_number); fprintf(stderr, "## max_filesize: %d\n", max_filesize); fprintf(stderr, "## do_html: %d (%s)\n", do_html, do_html ? "on" : "off"); } if (max_number==0 && max_filesize==0) { fprintf(stderr,"Either -n or -k must be specified to limit size of output\n"); usage(); } /* initialize random generator */ srand(seed); /* start output */ if (do_html) { printf(html_header); filesize=strlen(html_header); } else { filesize=0; } for (i=0; max_number==0 || imax_filesize && max_filesize>0) /* reached limit? */ break; printf(do_html ? "%s\n" : "%s\n", acc, acc); } return 0; }