#include #include #include #include struct hash { uint16_t hl; uint16_t bc; }; struct hash hashpass(uint8_t *password) { uint8_t c, b, c1; #define swap(x) (((x & 0x0f) << 4) | ((x & 0xf0) >> 4)) c = password[0] & 0xf; b = swap(password[0]) & 0x03; c = ((password[1] & 0xf) + swap(c)) & 0xff; b = ((swap(password[1]) & 0x03) + ((b << 2) & 0xff)) & 0xff; c1 = c; c = password[2] & 0xf; b = ((swap(password[2]) & 0x03) + ((b << 2) & 0xff)) & 0xff; c = ((password[3] & 0xf) + swap(c)) & 0xff; b = ((swap(password[3]) & 0x03) + ((b << 2) & 0xff)) & 0xff; #undef swap return (struct hash){.hl = (password[4] << 8) | b, .bc = (c << 8) | c1}; } bool validpass(struct hash password) { if ((password.hl & 0xe000) != 0) return false; if ((password.hl & 0x0007) != 0) return false; return true; } char *passchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?!"; void convpass(char *password, uint8_t *out) { for (int x = 0; x < 5; x++) { *out++ = strchr(passchars, *password++) - passchars; } } void hex_dump(const unsigned char *buf, unsigned size) { for (unsigned i = 0; i < size; i += 0x10) { printf(" "); for (unsigned x = i; x < i + 0x10 && x < size; x++) { printf(" %02X", buf[x]); } printf("\n"); } } int main(int argc, char *argv[]) { if (argc > 1 && strcmp(argv[1], "valid") == 0) { for (char **arg = argv + 2; arg < argv + argc; arg++) { uint8_t pwd[5]; convpass(*arg, pwd); hex_dump(pwd, sizeof(pwd)); struct hash hash = hashpass(pwd); printf("0x%04x 0x%04x\n", hash.hl, hash.bc); if (validpass(hash)) { printf("%s\n", *arg); } } return 0; } for (uint64_t x = 0; x < 0x40000000; x++) { uint8_t pwd[5]; uint64_t val = x; for (uint8_t *c = pwd; c < pwd + 5; c++) { *c = val % 64; val /= 64; } struct hash hash = hashpass(pwd); if (validpass(hash)) { for (uint8_t *c = pwd; c < pwd + 5; c++) { putchar_unlocked(passchars[*c]); } putchar_unlocked('\n'); } } }