Problem Set 2: Substitution
Evidence of a 5-point submission
- Uses a key validation method that requires only a single loop through the key; validate unique and alphabetic characters simultaneously using an array of size
ALPHASIZE
. - Stores substitution keys as all same-case letters (for efficiency later - only needs to convert one substitution to uppercase or lowercase during encryption)
- Uses an efficient method to encrypt plaintext (minimal repeated code, printing out the encrypted text directly instead of using a variable, uses the
isupper
andislower
functions) - Does not use 26 as a magic number
Evidence of a 4-point submission
- Uses a method better than exhaustive search to validate unique characters (does not use two nested for loops that both iterate
ALPHASIZE
times; may use an array of sizeALPHASIZE
but in a way that does not short-circuit - see implementation example) - Stores substitution keys as all same-case letters (for efficiency later - only needs to convert one substitution to uppercase or lowercase during encryption)
- Prints out encrypted text directly (does not store in a variable)
Evidence of a 3-point submission
- Uses an exhaustive iterative method to validate unique alphabetic characters that short circuits
- Uses a
for
loop to iterate through each character of the input and encrypt it
Evidence of a 2-point submission
- Uses a method worse than exhaustive (e.g., in O(n²)) to validate unique alphabetic characters (uses multiple nested loops to check the same characters more than once)
- Uses a non-constant time operation to find the index of the key to encrypt a given letter, when
plaintext[i] - 'a'
orplaintext[i] - 'A'
will do. - Loops over plaintext multiple times to encrypt
Evidence of a 1-point submission
- Uses a confusing method worse than exhaustive to validate unique alphabetic characters (checks for uniqueness in one nested loop, checks for alphabetic characters in a separate loop, doesn’t short-circuit)
- Uses a confusing and/or very unclear method for encryption
Example Implementations (Worse vs. Better)
Validate Key
Worse implementation
In the example below, though this method does use a key validation method check for duplicates, it does not short-circuit.
int letters[26];
for (int i = 0; i < 26; i++)
{
letters[i] = 0;
}
for (int i = 0; i < 26; i++)
{
int letter = tolower((int)(key[i]));
letters[letter - 'a']++;
}
for (int i = 0; i < 26; i++)
{
if (letters[i] != 1)
{
printf("invalid key\n");
return 1;
}
}
In the example below, the method uses an exhaustive check method, but the method will short-circuit.
for (int i = 0; i < 26; i++)
{
for (int j = 0; j < 26; j++)
{
if (i != j && s[i] == s[j])
{
return 1;
}
}
}
Better Implementation
The example below can be validated using O(1)-check calls. Simultaneously checks for alphabetical AND unique characters.
char substitution[ALPHASIZE] = {0};
bool used[ALPHASIZE] = {false};
for (int i = 0; i < ALPHASIZE; i++)
{
if (!isalpha(key[i]))
{
printf("Key must contain only alphabetic characters.\n");
return 1;
}
char c = toupper(key[i]);
if (used[c - 'A'])
{
printf("Key must not contain repeated characters.\n");
return 1;
}
used[c - 'A'] = true;
substitution[i] = c;
}