345 lines
7.4 KiB
Plaintext
345 lines
7.4 KiB
Plaintext
|
[List.HybridLeet:new]
|
||
|
int i, j;
|
||
|
int c, p;
|
||
|
int totrots;
|
||
|
int length;
|
||
|
|
||
|
/* Get the word length */
|
||
|
length = 0; while (word[length++]) ; --length;
|
||
|
|
||
|
/* Skip if this word length is out of bounds
|
||
|
This should not be necessary, but we'll leave it here to be defensive */
|
||
|
if (req_minlen > length || (req_maxlen && req_maxlen < length ))
|
||
|
{
|
||
|
hybrid_total = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Calculate word rotations */
|
||
|
|
||
|
word_rot_count=0; /* Number of letter positions we are rotating for this word */
|
||
|
totrots = 1; /* Number of total rotation iterations */
|
||
|
|
||
|
i=0;
|
||
|
while (i < length)
|
||
|
{
|
||
|
/* is this letter one of our rotators? a,A, b,B etc*/
|
||
|
c = word[i];
|
||
|
j = 0;
|
||
|
while (j < rot_poslen)
|
||
|
{
|
||
|
p = rot_pos[j];
|
||
|
if (c == rot_chars[p] || c == rot_chars[p+1]) /* Is 'a' or 'A' for example */
|
||
|
{
|
||
|
word_rot_idx[word_rot_count] = i; /* Save off which letter position in the word we are rotating */
|
||
|
word_rot_pos[word_rot_count] = j; /* Save off the rotation position for this slot */
|
||
|
word_rotchars_pos[word_rot_count] = p; /* Save off the first letter position in the rotation */
|
||
|
word_rot_count++;
|
||
|
|
||
|
/* Also, set the word to the first letter in the rotation so we ensure to go through all of them */
|
||
|
word[i] = rot_chars[p];
|
||
|
|
||
|
/* And multiple number of total rotations by the number of rotations for this position */
|
||
|
totrots = totrots * rot_len[j];
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
j++;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
hybrid_total = totrots;
|
||
|
|
||
|
/* Reset or counter for THIS word. */
|
||
|
word_rot_current = 0;
|
||
|
|
||
|
[List.External:HybridLeet]
|
||
|
|
||
|
/*
|
||
|
Static context
|
||
|
String lengths here are arbitrary, increase them if you increase the
|
||
|
size of the stuff in the init() procedure
|
||
|
*/
|
||
|
|
||
|
int rot_chars[256]; /* All characters to rotate */
|
||
|
int rot_charslen; /* The length of the rot_chars buffer */
|
||
|
|
||
|
int rot_len[26]; /* The number of characters to rotate through per letter */
|
||
|
int rot_pos[26]; /* The starting position of each letter group in the rot_chars string */
|
||
|
int rot_poslen; /* Length of rot_pos and rot_len arrays (both same size) */
|
||
|
|
||
|
int word_rot_idx[128]; /* The positions in the current word that require rotations (index into word)*/
|
||
|
int word_rot_pos[128]; /* The rot_pos index for each letter position in the current word that we are rotating (index into rot_pos)*/
|
||
|
int word_rotchars_pos[128]; /* The current rot_chars index for each letter position in the current word that we are rotating (state of rotation, index into rot_chars)*/
|
||
|
int word_rot_count; /* The number of letters that we are rotating in the current word (size of word_rot_idx, word_rot_pos, and word_rotchars_pos) */
|
||
|
|
||
|
int word_rot_current; /* The rotation number of the current word */
|
||
|
|
||
|
void init()
|
||
|
{
|
||
|
int rci;
|
||
|
int ri;
|
||
|
|
||
|
rot_charslen=0;
|
||
|
rci=0;
|
||
|
ri=0;
|
||
|
|
||
|
/* a */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'a'; /* The first two chars are always the lower */
|
||
|
rot_chars[rci++] = 'A'; /* and upper case letters to rotate on */
|
||
|
rot_chars[rci++] = '4';
|
||
|
rot_chars[rci++] = '@';
|
||
|
rot_chars[rci++] = '8';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* b */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'b';
|
||
|
rot_chars[rci++] = 'B';
|
||
|
rot_chars[rci++] = '8';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'c';
|
||
|
rot_chars[rci++] = 'C';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'd';
|
||
|
rot_chars[rci++] = 'D';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* e */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'e';
|
||
|
rot_chars[rci++] = 'E';
|
||
|
rot_chars[rci++] = '3';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'f';
|
||
|
rot_chars[rci++] = 'F';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'g';
|
||
|
rot_chars[rci++] = 'G';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* h */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'h';
|
||
|
rot_chars[rci++] = 'H';
|
||
|
rot_chars[rci++] = '#';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* i */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'i';
|
||
|
rot_chars[rci++] = 'I';
|
||
|
rot_chars[rci++] = '1';
|
||
|
rot_chars[rci++] = '!';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'j';
|
||
|
rot_chars[rci++] = 'J';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'k';
|
||
|
rot_chars[rci++] = 'K';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* l */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'l';
|
||
|
rot_chars[rci++] = 'L';
|
||
|
rot_chars[rci++] = '1';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'm';
|
||
|
rot_chars[rci++] = 'M';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'n';
|
||
|
rot_chars[rci++] = 'N';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* o */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'o';
|
||
|
rot_chars[rci++] = 'O';
|
||
|
rot_chars[rci++] = '0';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'p';
|
||
|
rot_chars[rci++] = 'P';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'q';
|
||
|
rot_chars[rci++] = 'Q';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'r';
|
||
|
rot_chars[rci++] = 'R';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* s */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 's';
|
||
|
rot_chars[rci++] = 'S';
|
||
|
rot_chars[rci++] = '$';
|
||
|
rot_chars[rci++] = '5';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
/* t */
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 't';
|
||
|
rot_chars[rci++] = 'T';
|
||
|
rot_chars[rci++] = '+';
|
||
|
rot_chars[rci++] = '7';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'u';
|
||
|
rot_chars[rci++] = 'U';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'v';
|
||
|
rot_chars[rci++] = 'V';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'w';
|
||
|
rot_chars[rci++] = 'W';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'x';
|
||
|
rot_chars[rci++] = 'X';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'y';
|
||
|
rot_chars[rci++] = 'Y';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_pos[ri] = rci;
|
||
|
rot_chars[rci++] = 'z';
|
||
|
rot_chars[rci++] = 'Z';
|
||
|
rot_len[ri] = (rci - rot_pos[ri]);
|
||
|
ri++;
|
||
|
|
||
|
rot_charslen = rci;
|
||
|
rot_poslen = ri;
|
||
|
|
||
|
}
|
||
|
|
||
|
/* new word */
|
||
|
void new()
|
||
|
{
|
||
|
.include [List.HybridLeet:new]
|
||
|
}
|
||
|
|
||
|
void next()
|
||
|
{
|
||
|
int i, j;
|
||
|
|
||
|
/* If we have reached the maximum number of rotations, we're done */
|
||
|
if (word_rot_current == hybrid_total)
|
||
|
{
|
||
|
word[0] = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* set word[] to the next candidate */
|
||
|
i=0;
|
||
|
while (i < word_rot_count)
|
||
|
{
|
||
|
/* Replace letter in word with appropriate rotated letter fom rot_chars */
|
||
|
word[word_rot_idx[i]] = rot_chars[word_rotchars_pos[i]];
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
/* Rotate the word_rotchars_pos */
|
||
|
i=0;
|
||
|
while (i < word_rot_count)
|
||
|
{
|
||
|
word_rotchars_pos[i]++;
|
||
|
|
||
|
j = word_rot_pos[i];
|
||
|
if (word_rotchars_pos[i] != (rot_pos[j] + rot_len[j]))
|
||
|
{
|
||
|
/* No carry */
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Rotation overflow, carry to next rotation */
|
||
|
word_rotchars_pos[i] = rot_pos[j];
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
word_rot_current++;
|
||
|
}
|
||
|
|
||
|
/* Called when restoring an interrupted session */
|
||
|
void restore()
|
||
|
{
|
||
|
int wrc;
|
||
|
|
||
|
.include [List.HybridLeet:new]
|
||
|
|
||
|
/* Pick up the current iteration */
|
||
|
word_rot_current = hybrid_resume;
|
||
|
|
||
|
/* Zoom the word_rotchars_pos to the hybrid_resume iteration */
|
||
|
i=0;
|
||
|
wrc = word_rot_current;
|
||
|
|
||
|
while (i < word_rot_count)
|
||
|
{
|
||
|
j = word_rot_pos[i];
|
||
|
|
||
|
/* Rotate this position */
|
||
|
word_rotchars_pos[i] = rot_pos[j] + (wrc % rot_len[j]);
|
||
|
wrc = wrc / rot_len[j];
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
}
|