/********************************************************************** * * * sjvalid.c (March 5, 2006): Solar Jetman password validator. * * * * Copyright 2003-2006 David Lawrence Ramsey * * * * Copyright 2006 Joel Yliluoma * * * * * * 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 2, 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., 51 Franklin St, Fifth Floor, Boston, * * MA 02110-1301, USA. * * * **********************************************************************/ #include #include int valid(const char *password) { const char *letter_set = "BDGHKLMNPQRTVWXZ"; int checksum[2], nibbles[5], answer, carry; if (strlen(password) != 12) return 0; if (strspn(password, letter_set) != 12) return 0; if (password[1] > letter_set[9] || password[4] > letter_set[9] || password[5] > letter_set[9] || password[6] > letter_set[9] || password[7] > letter_set[9] || password[10] > letter_set[11] || password[11] > letter_set[9]) return 0; #define VALUE(p) (strchr(letter_set, p) - letter_set) /* Many thanks to Joel Yliluoma for helping simplify this * function. */ nibbles[0] = (VALUE(password[0]) << 4) + VALUE(password[6]); nibbles[1] = (VALUE(password[1]) << 4) + VALUE(password[7]); nibbles[2] = (VALUE(password[2]) << 4) + VALUE(password[8]); nibbles[3] = (VALUE(password[4]) << 4) + VALUE(password[10]); nibbles[4] = (VALUE(password[5]) << 4) + VALUE(password[11]); answer = (nibbles[0] ^ nibbles[1]) + nibbles[2]; carry = (answer > 255); answer = (answer ^ nibbles[3]) + nibbles[4] + carry; checksum[0] = (answer >> 4) & 15; checksum[1] = answer & 15; if (checksum[0] != VALUE(password[3]) || checksum[1] != VALUE(password[9])) return 0; return 1; } int main(int argc, char **argv) { const char *password; int result; if (argc != 2) { fprintf(stderr, "Usage: sjvalid [password]\n"); return 1; } password = argv[1]; result = valid(password); printf("%s\n", (result == 1) ? "YES" : "NO"); return 0; }