2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * This program is copyright Alec Muffett 1993. The author disclaims all
10 * responsibility or liability with respect to it's usage or its effect
11 * upon hardware or computer systems, and maintains copyright as set out
12 * in the "LICENCE" document which accompanies distributions of Crack v4.0
20 #define RULE_PREPEND '^'
21 #define RULE_APPEND '$'
22 #define RULE_REVERSE 'r'
23 #define RULE_UPPERCASE 'u'
24 #define RULE_LOWERCASE 'l'
25 #define RULE_PLURALISE 'p'
26 #define RULE_CAPITALISE 'c'
27 #define RULE_DUPLICATE 'd'
28 #define RULE_REFLECT 'f'
29 #define RULE_SUBSTITUTE 's'
30 #define RULE_MATCH '/'
34 #define RULE_EXTRACT 'x'
35 #define RULE_OVERSTRIKE 'o'
36 #define RULE_INSERT 'i'
37 #define RULE_EQUALS '='
38 #define RULE_PURGE '@'
39 #define RULE_CLASS '?' /* class rule? socialist ethic in cracker? */
40 #define RULE_DFIRST '['
41 #define RULE_DLAST ']'
42 #define RULE_MFIRST '('
43 #define RULE_MLAST ')'
46 Suffix(char *myword
, char *suffix
)
55 return (STRCMP((myword
+ i
- j
), suffix
));
62 Reverse(register char *str
) /* return a pointer to a reversal */
66 static char area
[PATH_MAX
];
77 Uppercase(register char *str
) /* return a pointer to an uppercase */
80 static char area
[PATH_MAX
];
84 *(ptr
++) = CRACK_TOUPPER(*str
);
93 Lowercase(register char *str
) /* return a pointer to an lowercase */
96 static char area
[PATH_MAX
];
100 *(ptr
++) = CRACK_TOLOWER(*str
);
109 Capitalise(register char *str
) /* return a pointer to an capitalised */
112 static char area
[PATH_MAX
];
117 *(ptr
++) = CRACK_TOLOWER(*str
);
122 area
[0] = CRACK_TOUPPER(area
[0]);
127 Pluralise(register char *string
) /* returns a pointer to a plural */
130 static char area
[PATH_MAX
];
132 length
= strlen(string
);
133 (void) strlcpy(area
, string
, PATH_MAX
);
135 if (!Suffix(string
, "ch") ||
136 !Suffix(string
, "ex") ||
137 !Suffix(string
, "ix") ||
138 !Suffix(string
, "sh") ||
139 !Suffix(string
, "ss")) {
140 /* bench -> benches */
141 (void) strcat(area
, "es");
142 } else if (length
> 2 && string
[length
- 1] == 'y') {
143 if (strchr("aeiou", string
[length
- 2])) {
144 /* alloy -> alloys */
145 (void) strcat(area
, "s");
147 /* gully -> gullies */
148 (void) strcpy(area
+ length
- 1, "ies");
150 } else if (string
[length
- 1] == 's') {
152 (void) strcat(area
, "es");
155 (void) strcat(area
, "s");
162 Substitute(register char *string
, register char old
,
163 register char new) /* returns pointer to a swapped about copy */
166 static char area
[PATH_MAX
];
170 *(ptr
++) = (*string
== old
? new : *string
);
177 /* returns pointer to a purged copy */
179 Purge(register char *string
, register char target
)
182 static char area
[PATH_MAX
];
185 if (*string
!= target
) {
193 /* -------- CHARACTER CLASSES START HERE -------- */
196 * this function takes two inputs, a class identifier and a character, and
197 * returns non-null if the given character is a member of the class, based
198 * upon restrictions set out below
202 MatchClass(register char class, register char input
)
212 case '?': /* ?? -> ? */
218 /* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
221 case 'v': /* vowels */
222 c
= CRACK_TOLOWER(input
);
223 if (strchr("aeiou", c
)) {
229 case 'c': /* consonants */
230 c
= CRACK_TOLOWER(input
);
231 if (strchr("bcdfghjklmnpqrstvwxyz", c
)) {
237 case 'w': /* whitespace */
238 if (strchr("\t ", input
)) {
244 case 'p': /* punctuation */
245 if (strchr(".`,:;'!?\"", input
)) {
251 case 's': /* symbols */
252 if (strchr("$%%^&*()-_+=|\\[]{}#@/~", input
)) {
257 /* LOGICAL GROUPINGS */
260 case 'l': /* lowercase */
261 if (islower(input
)) {
267 case 'u': /* uppercase */
268 if (isupper(input
)) {
274 case 'a': /* alphabetic */
275 if (isalpha(input
)) {
281 case 'x': /* alphanumeric */
282 if (isalnum(input
)) {
288 case 'd': /* digits */
289 if (isdigit(input
)) {
295 if (isupper(class)) {
302 PolyStrchr(register char *string
, register char class)
305 if (MatchClass(class, *string
)) {
313 /* returns pointer to a swapped about copy */
315 PolySubst(register char *string
, register char class, register char new)
318 static char area
[PATH_MAX
];
322 *(ptr
++) = (MatchClass(class, *string
) ? new : *string
);
329 /* returns pointer to a purged copy */
331 PolyPurge(register char *string
, register char class)
334 static char area
[PATH_MAX
];
338 if (!MatchClass(class, *string
)) {
346 /* -------- BACK TO NORMALITY -------- */
349 Char2Int(char character
)
351 if (isdigit(character
)) {
352 return (character
- '0');
353 } else if (islower(character
)) {
354 return (character
- 'a' + 10);
355 } else if (isupper(character
)) {
356 return (character
- 'A' + 10);
361 /* returns a pointer to a controlled Mangle */
363 Mangle(char *input
, char *control
)
367 static char area
[PATH_MAX
];
368 char area2
[PATH_MAX
];
371 (void) strlcpy(area
, input
, PATH_MAX
);
373 for (ptr
= control
; *ptr
; ptr
++) {
378 (void) strlcpy(area
, Reverse(area
), PATH_MAX
);
381 (void) strlcpy(area
, Uppercase(area
), PATH_MAX
);
384 (void) strlcpy(area
, Lowercase(area
), PATH_MAX
);
386 case RULE_CAPITALISE
:
387 (void) strlcpy(area
, Capitalise(area
),
391 (void) strlcpy(area
, Pluralise(area
), PATH_MAX
);
394 (void) strlcat(area
, Reverse(area
), PATH_MAX
);
397 (void) strlcpy(area2
, area
, PATH_MAX
);
398 (void) strlcat(area
, area2
, PATH_MAX
);
404 limit
= Char2Int(*(++ptr
));
408 if (strlen(area
) <= limit
) {
417 limit
= Char2Int(*(++ptr
));
421 if (strlen(area
) >= limit
) {
431 (void) strlcpy(area2
+ 1, area
,
433 (void) strlcpy(area
, area2
, PATH_MAX
);
440 register char *string
;
444 string
[-1] = *(++ptr
);
449 if (!ptr
[1] || !ptr
[2]) {
456 start
= Char2Int(*(++ptr
));
457 length
= Char2Int(*(++ptr
));
458 if (start
< 0 || length
< 0) {
461 (void) strlcpy(area2
, area
, PATH_MAX
);
462 for (i
= 0; length
-- &&
463 area2
[start
+ i
]; i
++) {
464 area
[i
] = area2
[start
+ i
];
466 /* cant use strncpy()-no trailing NUL */
470 case RULE_OVERSTRIKE
:
471 if (!ptr
[1] || !ptr
[2]) {
476 i
= Char2Int(*(++ptr
));
488 if (!ptr
[1] || !ptr
[2]) {
495 i
= Char2Int(*(++ptr
));
506 (void) strlcpy(p2
, p1
, PATH_MAX
);
507 (void) strlcpy(area
, area2
, PATH_MAX
);
510 /* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
512 case RULE_PURGE
: /* @x or @?c */
513 if (!ptr
[1] || (ptr
[1] ==
514 RULE_CLASS
&& !ptr
[2])) {
516 } else if (ptr
[1] != RULE_CLASS
) {
517 (void) strlcpy(area
, Purge(area
,
518 *(++ptr
)), PATH_MAX
);
520 (void) strlcpy(area
, PolyPurge(area
,
525 case RULE_SUBSTITUTE
: /* sxy || s?cy */
526 if (!ptr
[1] || !ptr
[2] ||
527 (ptr
[1] == RULE_CLASS
&& !ptr
[3])) {
529 } else if (ptr
[1] != RULE_CLASS
) {
532 (void) strlcpy(area
, PolySubst(area
,
533 ptr
[2], ptr
[3]), PATH_MAX
);
537 case RULE_MATCH
: /* /x || /?c */
539 (ptr
[1] == RULE_CLASS
&& !ptr
[2])) {
541 } else if (ptr
[1] != RULE_CLASS
) {
542 if (!strchr(area
, *(++ptr
))) {
546 if (!PolyStrchr(area
, ptr
[2])) {
552 case RULE_NOT
: /* !x || !?c */
554 (ptr
[1] == RULE_CLASS
&& !ptr
[2])) {
556 } else if (ptr
[1] != RULE_CLASS
) {
557 if (strchr(area
, *(++ptr
))) {
561 if (PolyStrchr(area
, ptr
[2])) {
568 * alternative use for a boomerang, number 1: a standard throwing
569 * boomerang is an ideal thing to use to tuck the sheets under
570 * the mattress when making your bed. The streamlined shape of
571 * the boomerang allows it to slip easily 'twixt mattress and
572 * bedframe, and it's curve makes it very easy to hook sheets
576 case RULE_EQUALS
: /* =nx || =n?c */
577 if (!ptr
[1] || !ptr
[2] ||
578 (ptr
[2] == RULE_CLASS
&& !ptr
[3])) {
583 if ((i
= Char2Int(ptr
[1])) < 0) {
586 if (ptr
[2] != RULE_CLASS
) {
588 if (area
[i
] != *ptr
) {
593 if (!MatchClass(*ptr
,
605 for (i
= 1; area
[i
]; i
++) {
606 area
[i
- 1] = area
[i
];
616 for (i
= 1; area
[i
]; i
++);
623 (ptr
[1] == RULE_CLASS
&& !ptr
[2])) {
626 if (ptr
[1] != RULE_CLASS
) {
628 if (area
[0] != *ptr
) {
633 if (!MatchClass(*ptr
,
642 (ptr
[1] == RULE_CLASS
&& !ptr
[2])) {
647 for (i
= 0; area
[i
]; i
++);
654 if (ptr
[1] != RULE_CLASS
) {
656 if (area
[i
] != *ptr
) {
661 if (!MatchClass(*ptr
,
670 if (!area
[0]) { /* have we deweted de poor widdle fing away? */
677 * PMatch(register char *control, register char *string)
679 * while (*string && *control) {
680 * if (!MatchClass(*control, *string)) {
688 * if (*string || *control) {