Make any text l33t.
/**
* 't4rd' by Inky <http://boxofjunk.ws/>
* - v1.02 [14 May 2007] Rewritten; significantly less ugly
* - v0.01 [30 Apr 2007] The original
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define PROG_VERSION "1.02"
#define PROG_DATE "14 May 2007"
#define LETTERS 26
#define L_CASE 0
#define U_CASE 1
#define CTRL_D 4
/* Letter mutations */
#define MAX_MUTS 6
const char *muts[LETTERS][MAX_MUTS+1] = {
{ "4", "@" }, // a
{ "|3", "8" }, // b
{ "(", "<" }, // c
{ "|)" }, // d
{ "3" }, // e
{ "/=", "|=" }, // f
{ "9", "6" }, // g
{ "|-|", "/-/", "]-[" }, // h
{ "1", "|", "!" }, // i
{ "_|", "_/" }, // j
{ "|<" }, // k
{ "1", "|_" }, // l
{ "/\\/\\", "|\\/|", "|V|", "/V\\", "]V[", "/|\\" }, // m
{ "/\\/", "/V", "|\\|", "]\\[" }, // n
{ "0", "()" }, // o
{ "|>", "|\"", "|*" }, // p
{}, // q
{ "|2" }, // r
{ "5", "$" }, // s
{ "+", "7" }, // t
{ "|_|" }, // u
{ "\\/" }, // v
{ "\\/\\/", "vv", "\\^/", "\\|/" }, // w
{ "><", "}{", ")(" }, // x
{ "`/" }, // y
{} // z
};
unsigned short muts_len[26];
/* Convert a character to lowercase */
inline char chcase(const char chr, short charcase)
{
switch (charcase) {
case L_CASE:
return ((chr >= 'A' && chr <= 'Z') ? chr+0x20 : chr);
case U_CASE:
return ((chr >= 'a' && chr <= 'z') ? chr-0x20 : chr);
default:
return chr;
}
}
/* Print a letter in random case */
void putletter(const char chr)
{
unsigned short r = rand() % 3;
switch (r) {
case 1: // print in upper case
putchar(chcase(chr, U_CASE));
break;
case 2: // print in lower case
putchar(chcase(chr, L_CASE));
break;
default: // no change
putchar(chr);
}
}
/* t4rdify a string */
void t4rd(const char *str)
{
char c;
unsigned int i, m;
for (i = 0; str[i] != '\0'; i++) {
c = chcase(str[i], L_CASE);
if (c < 'a' || c > 'z') {
putchar(c);
} else {
m = muts_len[c-'a'];
if (m > 0) {
// 1 in 5 chance of printing
// a (relatively) normal letter
if (rand() % 5 == 1)
putletter(str[i]);
else
printf("%s", muts[c-'a'][rand() % m]);
} else {
putletter(c);
}
}
}
}
/* Run ze program! */
int main(int argc, char *argv[])
{
unsigned int i, j, len = 0, maxlen = 1024;
char in, *data;
// initialise stuff
srand(time(NULL));
for (i = 0; i < LETTERS; i++) {
for (j = 0; muts[i][j] != NULL; muts_len[i]++, j++);
}
if (argc > 1) {
// print help message
if (strcmp(argv[1], "--help") == 0 ||
strcmp(argv[1], "-h") == 0) {
printf("T4RD - version " PROG_VERSION
" by Inky, " PROG_DATE "\n\n");
printf("Usage: %s [TEXT]\n", argv[0]);
printf(" or: %s < [FILENAME]\n", argv[0]);
printf("\nReport bugs to <inky@boxo"
"fjunk.ws>\n");
exit(0);
}
// t4rdify the arguments
for (i = 1; i < argc; i++) {
t4rd(argv[i]);
putchar((i < argc-1) ? ' ' : '\n');
}
} else {
// read data from stdin and t4rdify it
data = (char*)malloc(sizeof(char) * maxlen);
while ((in = getchar()) != EOF && in != CTRL_D) {
// backspace
if (in == 8) {
if (len > 0) data[--len] = '\0';
continue;
}
// allocate memory for the string
if (len >= maxlen) {
maxlen <<= 1;
data = (char*)realloc(data,
sizeof(char) * maxlen);
}
data[len++] = in;
}
t4rd(data);
// print a trailing line break if needed
if (data[len-1] != '\n') putchar('\n');
}
return 0;
}