I've created a program that will find if a word is a palindrome or a reverse string (emordnilap
).
How it works:
The palindrome part works by reversing the string, and comparing the two strings using strcmp
to see if they match one another. If they do match, it will return true, if they do not match false.
How it checks if the word is a reverse string is by running through a wordlist line by line, stripping the string using a strip function and testing if the word is in the wordlist. Examples of usage:
e@ubuntu:~/bin/c$ ./epi.exe -h
usage: epi -h -t -s [string] [file]
-h Print this help and exit
-t Run the test strings.
-s Input a string to check if it is either a palindrome or
a emordinlap, followed by the path to a file.
e@ubuntu:~/bin/c$ ./epi.exe -t
'a' is a palindrome, it is the same forward and backwards
Reverse of 'a' is a emordnilap, it spells a word backwards.
'ab' is not a palindrome, it is not the same forward and backwards
Reverse of 'ab' is not a emordnilap, it does not spell a word backwards
'abc' is not a palindrome, it is not the same forward and backwards
Reverse of 'abc' is not a emordnilap, it does not spell a word backwards
'another' is not a palindrome, it is not the same forward and backwards
Reverse of 'another' is not a emordnilap, it does not spell a word backwards
'cbc' is a palindrome, it is the same forward and backwards
Reverse of 'cbc' is not a emordnilap, it does not spell a word backwards
'|0|' is a palindrome, it is the same forward and backwards
Reverse of '|0|' is not a emordnilap, it does not spell a word backwards
'palindrome' is not a palindrome, it is not the same forward and backwards
Reverse of 'palindrome' is not a emordnilap, it does not spell a word backwards // technically emordnilap is not a word
e@ubuntu:~/bin/c$ ./epi.exe -s
You must provide a string to test.
usage: epi -h -t -s [string] [file]
-h Print this help and exit
-t Run the test strings.
-s Input a string to check if it is either a palindrome or
a emordnilap, followed by the path to a file.
e@ubuntu:~/bin/c$ ./epi.exe -s test
You must pass a valid file path to use as a wordlist.
usage: epi -h -t -s [string] [file]
-h Print this help and exit
-t Run the test strings.
-s Input a string to check if it is either a palindrome or
a emordinlap, followed by the path to a file.
e@ubuntu:~/bin/c$ ./epi.exe -s test test.txt
'test' is not a palindrome, it is not the same forward and backwards
Reverse of 'test' is not a emordnilap, it does not spell a word backwards
e@ubuntu:~/bin/c$ ./epi.exe -s tset test.txt
'tset' is not a palindrome, it is not the same forward and backwards
Reverse of 'tset' is a emordnilap, it spells a word backwards.
e@ubuntu:~/bin/c$
Key points that I would like to focus on, of course critique the entire program:
- Is there a better way to reverse a string?
- Running through a file list, am I doing it properly?
- Could this program be simplified?
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
static void *helpPage(void)
{
puts("usage: epi -h -t -s [string] [file]\n");
puts("-h Print this help and exit\n");
puts("-t Run the test strings.\n");
puts("-s Input a string to check if it is either a palindrome or");
puts(" a emordnilap, followed by the path to a file.");;
}
static char *reverse(char *str)
{
// reverse a given string
char tmp, *src, *dst;
size_t len;
if (str != NULL)
{
len = strlen(str);
if (len > 1)
{
src = str;
dst = src + len - 1;
while (src < dst)
{
tmp = *src;
*src++ = *dst;
*dst-- = tmp;
}
}
}
return str;
}
static char *strip(char *s)
{
// strip a string of a new line
return strtok(s, "\n");
}
static bool checkEpi(char *reversed, char *filePath)
{
// check if the word matches in a given file
// or if the word is an emordnilap
FILE *wordList;
char *line = NULL;
size_t len = 0;
ssize_t read;
wordList = fopen(filePath, "r");
if (wordList == NULL)
{
perror("Failed to open file :"); // file probably doesn't exit
}
while ((read = getline(&line, &len, wordList)) != -1) // read the file line by line
{
if (strcmp(strip(line), reversed) == 0)
{
return true; // return true if the word matches
}
}
fclose(wordList);
}
static bool checkPali(char *origin, char *reversed)
{
// check if a given word is a palindrome or not
if (strcmp(origin, reversed) == 0)
{
return true;
}
else
{
return false;
}
}
static void checkAll(char *origin, char* reverse, char *filePath)
{
// basically a main function to check if it's a palindrome or a emordnilap
bool paliRes = checkPali(origin, reverse);
bool epiRes = checkEpi(reverse, filePath);
if (paliRes == true)
{
printf("\n'%s' is a palindrome, it is the same forward and backwards\n", origin);
}
else
{
printf("\n'%s' is not a palindrome, it is not the same forward and backwards\n", origin);
}
if (epiRes == true)
{
printf("Reverse of '%s' is a emordnilap, it spells a word backwards.\n\n", origin);
}
else
{
printf("Reverse of '%s' is not a emordnilap, it does not spell a word backwards\n\n", origin);
}
}
int main(int argc, char *argv[])
{
if (argv[1] == NULL)
{
puts("\nYou failed to pass a valid flag...\n");
helpPage();
return 1;
}
else
{
char *testStrings[] = {"a", "ab", "abc", "another", "cbc", "|0|", "palindrome"};
int i;
char s[10000];
char *defaultWordList = "/usr/share/dict/american-english";
size_t optInt;
for (optInt = 1; optInt < argc && argv[optInt][0] == '-'; optInt++)
{
switch(argv[optInt][1])
{
case 't':
{
for (i = 0; i < sizeof(testStrings) / sizeof(testStrings[0]); i++)
{
strcpy(s, testStrings[i]);
char *origin = testStrings[i];
char *revStr = reverse(s);
checkAll(origin, revStr, defaultWordList);
}
return 0;
}
case 's':
{
if (argv[2] == NULL)
{
puts("\nYou must provide a string to test.\n");
helpPage();
return 1;
}
else if (argv[3] == NULL)
{
puts("\nYou must pass a valid file path to use as a wordlist.\n");
helpPage();
return 1;
}
else
{
strcpy(s, argv[2]);
char *revStr = reverse(s);
checkAll(argv[2], revStr, argv[3]);
return 0;
}
}
case 'h': helpPage(); return 0;
}
}
return 0;
}
}
printf
be used for exploitation? \$\endgroup\$helpPage
function. \$\endgroup\$