Created
November 17, 2015 13:47
-
-
Save semahawk/212fab6592586d1b0503 to your computer and use it in GitHub Desktop.
Fallout-like password-guessing game in C.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* szomon :] */ | |
/* | |
* Fallout-like password-guessing game. | |
* | |
* Copyright: Szymon Urbaś | |
* Licensed under the BSD (2-clause) license. | |
*/ | |
#include <ctype.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <time.h> | |
#define ATTEMPTS 5 | |
#define GODMODE 0 | |
#define DEBUG 0 | |
#define ARR_SIZE(a) (sizeof(a) / sizeof(*a)) | |
int main(void) | |
{ | |
char *passwords[] = { | |
/* works when passwords have different length | |
* but that's actually a dumb thing to do. */ | |
"VIRAL", | |
"DARED", | |
"MINES", | |
"PARTS", | |
"LIKES", | |
"HAREM", | |
"THREW", | |
"SORTS", | |
"FARTS" | |
}; | |
char input[256]; | |
char *password; | |
unsigned count = 0; | |
int attempts = ATTEMPTS; | |
int occurrences[26] = { 0 }; | |
int seen[26] = { 0 }; | |
int n; | |
char *i, *p; | |
char **pp; | |
char *lf, *cr; | |
srand(time(NULL)); | |
/* pick a random password */ | |
password = passwords[rand() % ARR_SIZE(passwords)]; | |
#if GODMODE | |
printf("GODMODE: password is %s\n\n", password); | |
#endif | |
/* print out the table with possible passwords */ | |
for (n = 0; n < (ARR_SIZE(passwords) & ~1); n += 2){ | |
printf(" 0x%08x %-7s", rand(), passwords[n + 0]); | |
printf(" 0x%08x %s\n", rand(), passwords[n + 1]); | |
} | |
/* print the 'odd' password if there's any */ | |
if (ARR_SIZE(passwords) & 1){ | |
printf(" 0x%08x %s\n", rand(), passwords[ARR_SIZE(passwords) - 1]); | |
} | |
printf("\n"); | |
/* the actual guessing */ | |
do { | |
/* zero-out */ | |
count = 0; | |
memset(occurrences, 0, sizeof(occurrences)); | |
memset(seen, 0, sizeof(seen)); | |
/* print the number of attempts and the 'boxes' */ | |
printf("%u attempt%s left! ", attempts, attempts == 1 ? "" : "s"); | |
for (n = 0; n < attempts; n++) printf("#"); | |
printf("\n"); | |
/* print the prompt */ | |
printf(" > "); | |
/* fetch the input */ | |
fgets(input, 256, stdin); | |
/* chomp */ | |
if ((lf = strrchr(input, '\n'))) *lf = '\0'; | |
if ((cr = strrchr(input, '\r'))) *cr = '\0'; | |
/* count how many times each letter in the alphabet appears in the | |
* password */ | |
for (p = password; *p != '\0'; p++){ | |
occurrences[tolower(*p) - 'a']++; | |
} | |
/* go over every character in the input.. */ | |
for (i = input; *i != '\0'; i++){ | |
/* ignore any non-alphabetic characters */ | |
if (!isalpha(*i)) | |
continue; | |
/* go over every character in the password and see if there's a match */ | |
for (p = password; *p != '\0'; p++){ | |
unsigned idx = tolower(*i) - 'a'; | |
/* this bit is magic so I won't explain it */ | |
if ((seen[idx] < occurrences[idx]) && (tolower(*i) == tolower(*p))){ | |
#if DEBUG | |
printf("char '%c' in input is equal to char '%c' in password\n", *i, *p); | |
#endif | |
seen[idx]++; | |
count++; | |
break; | |
} | |
} | |
} | |
if (strcmp(input, password)){ | |
printf("Incorrect! %u/%lu characters right\n", count, strlen(password)); | |
} else { | |
printf("Exact match! +75XP\n"); | |
return 0; | |
} | |
} while (--attempts); | |
if (!attempts){ | |
printf("You have been temporarily locked out! Contact your's system administrator!\n"); | |
return 1; | |
} | |
return 0; | |
} | |
/* | |
* vi: ft=c:ts=2:sw=2:expandtab | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment