For this assignment you will be implementing several algorithms for working with ASCII strings, as well as encryption and decryption algorithms for a variant of the homophonic substitution cipheβΒ Β Β Β Β Β Β Β Β Β Β Β Β r. In thisβΒ Β Β Β Β Β Β Β Β Β Β Β Β cipher, some of the letters from the plaintextβΒ Β Β Β Β β (the input message) can be replaced with one of several different possible letters to generate the ciphertextβΒ Β Β Β Β Β β (the encrypted output message). This is in contrast with a traditional substitution cipher, wherein there is only one option to substitute for each plaintext letter. If you are unfamiliar with substitution ciphers, we recommend you briefly review the WikipediβΒ Β a article on the topic.β
Β
As a concrete example, suppose the plaintext alphabetβ β is:
Β
aaaaaaabcdeeeeeeeeefghhiiiijklmnnnnnoooooopqrrrsttttttttuvwxyz
Β
and the ciphertext alphabetβ β is:
Β
WhatsSewolfImAOF20BUCVD19ZEdinbcgjkpqruvxyzGHJKLMNPQRTXY345678
Β
The above alphabets indicate that βaβ can be replaced any of the characters βWhatsSeβΒ Β Β Β Β Β Β Β β in theβ ciphertext; βnβ can be replaced with any of the characters βcgjkpβΒ Β Β Β Β Β Β Β Β Β Β Β Β Β β, and so on;β
Β
In our cipher, encryption and decryption require two secret pieces of information: a keyphraseβΒ Β Β Β Β Β Β Β β, which is intended to be an easily-remembered phrase or sentence, and a longer corpusβΒ Β Β Β β, which is at least several sentences of text from a document that can be easily obtained (e.g., from a library, the Web, etc.) In a homophonic substitution cipher, the idea is that a letter which occurs frequently in English text can be substituted with any of several possible characters, not just the same character every time. This makes it harder to crack the code. Less-frequently occurring letters might be substituted with only a handful of letters in the ciphertext, or perhaps only even one. The corpus text is used in the frequency analysis to decide how many different possible substitutions could be performed for each plaintext letter. The keyphrase determines the order of the symbols in the ciphertext alphabet, which contains the characters which will be substituted for the plaintext letters. All of this will become clearer as we work through an example.
Β
Encryption Phase 1: Create the Ciphertext Alphabet using the Keyphrase
Β
Our ciphertext alphabet contains 62 symbols that will be used to replace the plaintext letters: 26 lowercase letters, 26 uppercase letters and 10 digit characters provide the 62 symbols.
Β
- Initialize an empty ciphertext alphabet consisting of 62 bytes.
- Draw letters and digit characters one at a time from the keyphrase, left-to-right, possibly adding each character to the ciphertext alphabet. Ignore spaces and punctuation marks.
- If a drawn character has not already been added to the ciphertext alphabet, then add it to the end.
- Otherwise, skip that character and move on to the next character of the keyphrase.
- After drawing all alphanumeric characters from the keyphrase, determine which lowercase letters do not appear in the ciphertext alphabet. Add these missing letters in alphabetical order to the ciphertext alphabet.
- Repeat step 3, but for uppercase letters.
- Repeat step 3. but for digit characters.
Β
As an example, suppose the keyphrase is:
Β
Whatβs a Seawolf? Iβm a SeAwOlF! Fall 2020 SBU: COVID-19 Zoom Edition
Β
After step 2, the (incomplete) ciphertext alphabet will consist of these characters:
Β
WhatsSewolfImAOF20BUCVD19ZEdin
Β
After step 3, the missing lowercase letters have been appended to yield:
Β
WhatsSewolfImAOF20BUCVD19ZEdinbcgjkpqruvxyzβ
Β
After step 4, the missing uppercase letters have been appended to yield:
Β
WhatsSewolfImAOF20BUCVD19ZEdinbcgjkpqruvxyzβΒ GHJKLMNPQRTXYβ
Β
After step 5, the missing digit characters have been appended to yield the final ciphertext alphabet:
Β
WhatsSewolfImAOF20BUCVD19ZEdinbcgjkpqruvxyzβΒ GHJKLMNPQRTXYβΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β 345678β
Β
Encryption Phase 2: Compute the Frequency of Letters in the Corpus and Assign Substitutions
Β
In this phase, we first count the number of times each letter occurs in the corpus, ignoring case. Then, we sort the letters into descending order by count. In other words, the most frequently occurring letters are placed near the front of the sorted alphabet. If two letters have the same frequency, the one with the lower ASCII value is placed in front of the other.
Β
Consider the following text, used as the corpus:
Β
Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.
Β
This text generates the following case-insensitive counts:
Β
a 46Β Β b 3Β Β c 14Β Β d 21Β Β e 57Β Β f 9Β Β g 13Β Β h 23Β Β i 32Β Β j 0Β Β k
0 l 14Β Β m 4Β Β n 35Β Β o 37Β Β pΒ 6Β Β q 1Β Β r 28Β Β s 16Β Β t 52Β Β u 6Β Β v
8 wΒ 8Β Β x 0Β Β yΒ 3Β Β zΒ 0
Β
Sorting the letters according the criteria explained above yields the string:
Β
etaonirhdsclgfvwpumbyqjkxz
Β
Next, to generate the plaintext alphabet, we duplicate the most frequently occurring letter eight times, the second most frequently occurring letter seven times, β¦, and the eighth most frequently occurring letter once. (Note that 8+7+6+5+4+3+2+1 = 36 and that 26+36 = 62.) For our example, we obtain:
Β
aaaaaaabcdeeeeeeeeefghhiiiijklmnnnnnoooooopqrrrsttttttttuvwxyz
Β
Note that βeβ is repeated eight times, the βtβ is repeated seven times, the βaβ is repeated six times, etc. The βhβ, which is the eighth most frequently occurring letter, is repeated only once. All other letters appear only once each. Note that the plaintext alphabet contains only lowercase letters. This means that any uppercase letters in the input message must be changed to lowercase during the encryption process.
Β
Encryption Phase 3: Perform Substitutions to Generate the Ciphertext
Β
Now we lay the plaintext alphabet on top of the ciphertext alphabet:
Β
aaaaaaabcdeeeeeeeeefghhiiiijklmnnnnnoooooopqrrrsttttttttuvwxyz
WhatsSewolfImAOF20BUCVD19ZEdinbcgjkpqruvxyzGHJKLMNPQRTXY345678
Β
We see that, in theory, βaβ can be replaced with any of the seven characters from the string βWhatsSeβ; βbβ can be replaced only with βwβ; βcβ can be replaced only with βoβ; βdβ can be replaced only with βlβ; βeβ can be replaced with any of the nine characters from βfImAOF20Bβ, and so on. To make this selection process deterministic (non-random), we will use the index of a character from the plaintext modulo βΒ Β Β Β βthe number of instances of a character to choose the substituted character from the ciphertext alphabet. For instance, suppose there is a letter βeβ at index 12 of the plaintext. Note that there are nine instances of βeβ in the ciphertext alphabet. 12 mod 9 = 3, so we take the character at index 3 of the string
βfImAOF20Bβ, which is βAβ. Note that in all computations we assume that indexes strings and substrings are 0-based. Namely, the leftmost character of the plaintext is 0; the characters of the plaintext alphabet and ciphertext alphabet are indexed 0 through 61 (inclusive); substrings drawn from the ciphertext alphabet are indexed starting from 0, etc. Finally, note that only lowercase letters from the plaintext are encrypted; all other characters (punctuation marks, spaces, etc.) are merely copied to the ciphertext unencrypted. We will assume for this assignment that the plaintext message will never contain digits.
Β
Part 1: Compute the Length of a Null-terminated String
Β
int strlen(string str)
Β
This function takes a null-terminated string (possibly empty) and returns its length (i.e., the number of characters in the string). The null-terminator is guaranteed to be present and is not counted in the length.
Β
The function takes one argument:
- str:β the starting address of a null-terminated string
Β
Returns in $v0:
- The number of characters in the string, not including the null-terminator.
Β
Additional requirements:
- The function must not write any changes to main memory.
Β
Examples:
Β
| Function Argument | Return Value |
| βWolfie Seawolf!!! 2020??β | 24 |
| βMIPSβ | 4 |
| ββΒ Β Β Β Β (β empty string, containing only \0) | 0 |
Β
Β
Part 2: Find the Index of a Character in a Null-terminated String
Β
int index_of(string str, char ch, int start_index)
Β
The function returns the index of the first instance of βprintable characterβ βchβ in the null-terminated string strβ, starting the search at index βstart_indexβ and moving to the right (towards higher indexes). If the character is not present in the string or if βstart_indexβ is not a valid index for βstrβ, the function returns -1. It is possible that the string is empty.
Β
The function takes the following arguments, in this order:
- strβ: the starting address of a null-terminated string
- chβ: the printable character to search for
- start_indexβ: the index at which the search begins
Β
Returns in $v0:
- The index of the leftmost occurrence of βchβ in βstrβ found at index βstart_indexβ or to the right of βstart_indexβ; or -1 if βchβ is not found during the search or if βstart_indexβ is not a valid index for βstrβ.
Β
Additional requirements:
- The function must not write any changes to main memory.
- The function must call βstrlenβ.
Β
Examples:
Β
| Function Arguments | Return Value |
| βCSE 220 COVID-19 Editionβ, βVβ, 3 | 10 |
| βCSE 220 COVID-19 Editionβ, βVβ, 13 | -1 |
| βCSE 220 COVID-19 Editionβ, βnβ, 5 | 23 |
| βCSE 220 COVID-19 Editionβ, βnβ, -5 | -1 |
| ββ, βzβ, 0 | -1 |
Β
Β
Part 3: Convert a Null-terminated String to Lowercase
Β
int to_lowercase(string str)
Β
This function takes a null-terminated string (possibly empty) and changes all of its uppercase letters to lowercase. All other characters in the string remain unchanged.
Β
The function takes one argument:
- str:β the starting address of a null-terminated string
Β
Returns in $v0:
- The number of letters changed from uppercase to lowercase.
Β
Additional requirements:
- The function must not write any changes to main memory except for strβ .β
Β
Examples:
Β
| Function Arguments | Return Value |
| βStony Brook Universityβ | 3 |
| βUNIVERSITYβ | 10 |
| β2020-2021β | 0 |
| ββ | 0 |
Β
Β
Part 4: Generate the Ciphertext Alphabet from a Keyphrase
Β
int generate_ciphertext_alphabet(string ciphertext_alphabet,Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β string keyphrase)
Β
This function generates the ciphertext alphabet as described in Encryption Phase 1 in the Preliminaries section of the document above. The function must null-terminate ciphertext_alphabetβΒ Β Β Β Β Β Β by writing aβΒ Β Β Β Β null-terminator at ciphertext_alphabet[62]βΒ Β Β Β Β Β Β Β Β Β Β .β
Β
The function takes the following arguments, in this order:
- ciphertext_alphabet:β an uninitialized buffer of 63 contiguous bytes of main memory where the function writes the ciphertext alphabet.
- keyphrase:β a non-empty, null-terminated string to serve as the keyphrase
Β
Returns in $v0:
- The number of unique, case-sensitive alphanumerical characters drawn from keyphraseβ .β
Β
Additional requirements:
- The function must not write any changes to main memory except for ciphertext_alphabetβ .β For example, the string keyphraseβΒ Β Β Β Β Β Β Β Β Β Β Β Β Β must remain unchanged.β
Β
Example #1:
Β
keyphrase = βStony Brook Universityβ Resulting ciphertext_alphabet:β
βStonyBrkUivesabcdfghjlmpquwxzACDEFGHIJKLMNOPQRTVWXYZ0123456789
β
Β
Returns in $v0: 13β
Β
Example #2:
Β
keyphrase = βMonday, September 21st, 2020 4:39 PM EDTβ Resulting ciphertext_alphabetβΒ Β Β :β
βMondaySeptmbr21s0439PEDTcfghijklquvwxzABCFGHIJKLNOQRUVWXYZ5678
β
Β
Returns in $v0: 24β
Β
Example #3:
Β
keyphrase = βsuPeRcalIfrAgiListICexPiaLIdoCIOusβ Resulting ciphertext_alphabetβΒ Β :β
βsuPeRcalIfrAgiLtCxdoObhjkmnpqvwyzBDEFGHJKMNQSTUVWXYZ0123456789β
Β
Returns in $v0: 21β
Β
Β
Part 5: Count the Occurrences of Each Lowercase Letter in a String
Β
int count_lowercase_letters(int[] counts, string message)
Β
This function counts the number of times each lowercase letter occurs in βmessageβ, storing those counts in βcountsβ. Specifically, βcounts[0]β stores the number of instances of βaβ in βmessageβ, counts[1]β the number of instances of βbβ in βmessageβ, etc. Note that each element in βcountsβ is a 4-byte integer. βcountsβ is not initialized with zeros when the function is called.
Β
The function takes the following arguments, in this order:
- countsβ: an uninitialized buffer of 26 contiguous words of main memory where the function writes the counts of the lowercase letters.
- messageβ: a null-terminated string (possibly empty) that could consist of any characters with ASCII codes 32 through 126, inclusive
Β
Returns in $v0:
- The total number of lowercase letters in βmessageβ.
Β
Additional requirements:
- The function must not write any changes to main memory except for βcountsβ. For example, the string βmessageβ must remain unchanged.
Β
Example #1:
Β
message = βThe specialization in artificial intelligence and data science emphasizes modern approaches for building intelligent systems using machine learning.β
Β
Resulting βcountsβ: β12 1 7 4 16 2 5 4 18 0 0 8 4 14 4 4 0 5 9 7 2 0 0 0 1 2
Β
which means:
Β
a:12Β Β b: 1Β Β c: 7Β Β d: 4Β Β e:16Β Β f: 2Β Β g: 5Β Β h: 4Β Β i:18Β Β j: 0Β Β k: 0 l: 8Β Β m: 4Β Β n:14Β Β o: 4 Β Β p: 4Β Β q: 0Β Β r: 5Β Β s: 9Β Β t: 7Β Β u: 2Β Β v: 0 w: 0Β Β x: 0Β Β y: 1Β Β z: 2
Β
Return value in $v0: β129
Β
Example #2:
Β
message = βWe can only see a short distance ahead, but we can see plenty there that needs to be done. -Alan Turingβ
Β
Resulting βcountsβ: β8 2 3 4 15 0 1 4 2 0 0 3 0 9 4 1 0 3 5 8 2 0 1 0 2 0
Β
which means:
Β
a: 8Β Β b: 2Β Β c: 3Β Β d: 4Β Β e:15Β Β f: 0Β Β g: 1Β Β h: 4Β Β i: 2Β Β j: 0Β Β k: 0 l: 3Β Β m: 0Β Β n: 9Β Β o: 4Β Β p: 1Β Β q: 0Β Β r: 3Β Β s: 5Β Β t: 8Β Β u: 2Β Β v: 0 w: 1Β Β x: 0Β Β y: 2Β Β z: 0
Β
Return value in $v0: β77
Β
Β
Part 6: Sort the Letters of the Alphabet by Frequency
Β
void sort_alphabet_by_count(string sorted_alphabet, int[] counts)
Β
This functionβs purpose is to sort the lowercase letters of the Latin alphabet using the numbers given in the βcountsβ array as the sorting key, storing that sorted alphabet in βsorted_alphabetβ.Β The buffer sorted_alphabetβ is guaranteed to be at least 27 bytes in size. The 26-word βcounts βarray provides a non-negative integer count associated with each lowercase letter. Specifically, βcounts[0]β is the count for βaβ, βcounts[1]β is the count for βbβ, etc. The function sorts the contents of sorted_alphabetβ so that the letter with highest count is at index 0, the letter with second-highest count is at index 1, and so. When two or more letters have the same count, the letter with smallest ASCII value is placed before the others in βsorted_alphabetβ, the letter with second-smallest ASCII value immediately follows the letter with smallest ASCII value, etc. The function null-terminates sorted_alphabetβ by writing a null-terminator at βsorted_alphabet[26]β.
Β
The function takes the following arguments, in this order:
- sorted_alphabetβ: an uninitialized buffer of 27 contiguous bytes of main memory.
- countsβ: an array of 26 non-negative counts. Each integer is four bytes. Note that this array is not necessarily the output of the βcount_lowercase_lettersβ function, so do not assume that when coding this function.
Β
Additional requirements:
- The function must not write any changes to main memory except for βsorted_alphabetβ and
countsβ.
Β
Example #1:
Β
counts = 28 13 24 2 28 19 12 2 0 10 23 14 3 28 1 2 21 4 4 25 29 0 9 29 13 18
Resulting βsorted_alphabetβ: ββuxaentckqfzlbygjwrsmdhpoivβ
Β
Example #2:
Β
counts = 21 17 20 25 21 19 28 26 15 16 21 13 11 16 1 27 24 20 5 23 26 2 29 15 21 8
Resulting βsorted_alphabetβ: βwgphudqtaekycrfbjnixlmzsvoββ
Β
Example #3:
Β
counts = 23 26 29 1 20 9 15 30 24 20 23 7 17 15 5 4 17 14 12 24 14 1 0 4 14 6
Resulting βsorted_alphabetβ: βhcbitakejmqgnruysflzopxdvwββ
Β
Β
Part 7: Generate the Plaintext Alphabet from a Sorted Alphabet
Β
void generate_plaintext_alphabet(string plaintext_alphabet,Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β string sorted_alphabet)
Β
This function generates the 62-character plaintext alphabet from a sorted lowercase Latin alphabet using the algorithm described in Encryption Phase 2 under Preliminaries earlier in this document. The plaintext alphabet is written into the uninitialized βplaintext_alphabetβ buffer, which is guaranteed to be at least 63 bytes in size. The function null-terminates βplaintext_alphabetβ by writing a null-terminator at βplaintext_alphabet[62]β. Briefly, the plaintext alphabet contains the lowercase letters of the Latin alphabet in alphabetical order, except that βsorted_alphabet[0]β is repeated 8 times in βplaintext_alphabetβ, βsorted_alphabet[1]β is repeated 7 times in plaintext_alphabetβ, etc., all the way to βsorted_alphabet[7]β, which is repeated once in plaintext_alphabetβ. The remaining 18 letters of βsorted_alphabetβ each appears once in plaintext_alphabetβ.
Β
The function takes the following arguments, in this order:
- plaintext_alphabetβ: an uninitialized buffer of 63 contiguous bytes of main memory where the function writes the 62-character plaintext alphabet, ending with a null-terminator
- sorted_alphabetβ: a null-terminated string containing the 26 lowercase letters of the Latin alphabet, in any order
Β
Additional requirements:
- The function must not write any changes to main memory except for βplaintext_alphabet and βsorted_alphabetβ.
Β
Example #1:
Β
sorted_alphabet = βegljhotupvfsxawqkrmzdyncibβ Resulting βplaintext_alphabetβ:
βabcdeeeeeeeeefgggggggghhhhhijjjjjjklllllllmnoooopqrstttuuvwxyz
β
Β
Example #2:
Β
sorted_alphabet = βeznovrqbdatjghlwmskyipcxfuβ Resulting βplaintext_alphabetβ:
βabbcdeeeeeeeeefghijklmnnnnnnnoooooopqqqrrrrstuvvvvvwxyzzzzzzzz
β
Β
Example #3:
Β
sorted_alphabet = βjmhoxqzgityudwsecvfalnkrbpβ
Resulting plaintext_alphabetβΒ :β
βabcdefgghhhhhhhijjjjjjjjjklmmmmmmmmnoooooopqqqqrstuvwxxxxxyzzz
β
Β
Β
Part 8: Return the Ciphertext Character Substituted for a Letter from the Plaintext
Β
int encrypt_letter(char plaintext_letter, int letter_index,
string plaintext_alphabet, string ciphertext_alphabet)
Β
This function computes and returns the substitution of a plaintext letter for the ciphertext, given the plaintext letter itself, that letterβs index in the plaintext message, the plaintext alphabet as generated by generate_plaintext_alphabet and the ciphertext alphabet as generated byβΒ generate_ciphertext_alphabet. The substitution process is described in Encryption Phase 3 inβΒ Β the Preliminaries section of the document, above. Briefly, suppose the plaintext_letterβΒ Β Β Β Β Β Β Β Β Β Β Β Β (locatedβ at index letter_indexβΒ Β Β Β Β Β Β Β of some plaintext) appears at indexes βΒ Β Β Β Β Β Β Β Β Β Β iβ through β i+kβΒ Β Β Β Β Β ofβΒ Β Β Β Β Β Β Β Β plaintext_alphabet. The function will return the character at locationβΒ Β Β Β Β Β Β Β Β Β Β Β Β Β ciphertext_alphabet[i+(letter_index mod (k+1))]. Note that it is this functionβsβ responsibility to determine the value of kβ for a given letter in β plaintext_alphabetβΒ Β Β Β Β Β Β Β Β Β .β
Β
The function takes the following arguments, in this order:
- plaintext_letter:β a lowercase letter
- letter_index:β a non-negative integer
- plaintext_alphabet:β the 62-character plaintext alphabet required to encrypt a plaintext message
- ciphertext_alphabet:β the 62-character ciphertext alphabet required to encrypt a plaintext message
Β
Returns in $v0:
- The encrypted letter or -1 if plaintext_letterβ is not a lowercase letter.β
Β
Additional requirements:
- The function must not write any changes to main memory.
Β
Example #1:
Β
plaintext_letter = βuβ letter_index = 3 plaintext_alphabet =
βabbbbbbbbcdefffffffgggghiiijkklmnopqrstuuuuuvvvvvvwxxxxxxxxxyz
β ciphertext_alphabet =
βStonyBrkUivesNwYadfAmcbghjlpquxzCDEFGHIJKLMOPQRTVWXZ0123456789
β
Β
Return value in $v0: 77β (ASCII code for β βMββ )β
Β
Example #2:
Β
plaintext_letter = βpβ letter_index = 46 plaintext_alphabet =
βabcdeeefghijkkkkkkkllllllmmnoppppppppqrstuvvvvvwxyyyyzzzzzzzzz
β ciphertext_alphabet =
βStonyBrkUivesNwYadfAmcbghjlpquxzCDEFGHIJKLMOPQRTVWXZ0123456789
β
Β
Return value in $v0: 70β Β (ASCII code for β βFββ )β
Β
Example #3:
Β
plaintext_letter = βxβ letter_index = 37 plaintext_alphabet =
βabcccccdeeeeeeeeeffffffffgghijkkklmnoppppqrstuvwxxxxxxyzzzzzzz
β ciphertext_alphabet =
βStonyBrkUivesNwYadfAmcbghjlpquxzCDEFGHIJKLMOPQRTVWXZ0123456789
β
Β
Return value in $v0: 87β (ASCII code for β βWββ )β
Β
Example #4:
Β
plaintext_letter = βnβ letter_index = 15 plaintext_alphabet =
βabccccccccdddddefghiiiiiijjjjjjjjjklmmnopqrstuvwwwwwwwxyyyyzzz
β ciphertext_alphabet =
βStonyBrkUivesNwYadfAmcbghjlpquxzCDEFGHIJKLMOPQRTVWXZ0123456789
β
Β
Return value in $v0: 73β (ASCII code for β βIββ )β
Β
Β
Part 9: Encrypt a Plaintext Message using a Homophonic Substitution Cipher
Β
int, int encrypt(string ciphertext, string plaintext, string keyphrase,Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β string corpus)
Β
This function encrypts the given βnon-emptyβ plaintext message using the homophonic substitution cipher described earlier in the document, storing the resulting ciphertext in βciphertextβ. Assume that the plaintext contains only letters, spaces and punctuation marks; no digits will be present in the plaintext. All arguments are assumed to be valid. The buffer for the ciphertext is guaranteed to be large enough to store the null-terminated βciphertextβ. Note that the function returns two values.
Β
The function takes the following arguments, in this order:
- ciphertextβ: an uninitialized buffer to store the encrypted plaintext
- plaintextβ: a βnon-emptyβ, null-terminated, string to be encrypted using the homophonic substitution cipher
- keyphraseβ: a βnon-emptyβ, null-terminated keyphrase string used during the encryption process
- corpusβ: a βnon-emptyβ, null-terminated corpus string used during the encryption process
Β
The function implements the following algorithm:
- Call βto_lowercaseβ on both βplaintextβ and βcorpusβ.
- Allocate at least 26 wordsβ worth of memory on the stack to temporarily store the βcountsβ array needed in the following step. (How? Simply subtract however many bytes you want to allocate from $sp. Make sure the number of bytes you allocate is a multiple of 4.) Be sure to deallocate this memory later.
- Call βcount_lowercase_letters(counts, corpus)β.
- Allocate at least 27 bytes of memory on the stack to store the βlowercase_lettersβ string needed in the following step. Be sure to deallocate this memory later.
- Call βsort_alphabet_by_count(lowercase_letters, counts)β.
- Allocate at least 63 bytes of memory on the stack to temporarily store the plaintext_alphabetβ string needed in the following step. Be sure to deallocate this memory later.
- Call βgenerate_plaintext_alphabet(plaintext_alphabet, lowercase_letters)β.
- Allocate at least 63 bytes of memory on the stack to temporarily store the ciphertext_alphabetβ string needed in the following step. Be sure to deallocate this memory later.
- Call βgenerate_ciphertext_alphabet(ciphertext_alphabet, keyphrase)β.
- In a loop, call βencrypt_letterβ to encrypt each lowercase letter of βplaintextβ and write the return value into βciphertextβ. Each non-lowercase letter of βplaintextβ should not be passed as an argument to βencrypt_letterβ, but should instead simply be copied to βciphertextβ.
- Null-terminate the βciphertextβ
Β
Returns in $v0:
- The number of lowercase letters that were encrypted during the encryption process.
Β
Returns in $v1:
- The number of characters from the plaintext that were not encrypted and simply copied to ciphertext.β
Β
Additional requirements:
- The function must not write any changes to main memory except as needed.
- The function must call the functions to_lowercaseβ (twice), β count_lowercase_lettersβ ,β sort_alphabet_by_count, β generate_ciphertext_alphabetβ ,β generate_plaintext_alphabet, and β encrypt_letterβ .β
Β
Example #1:
Β
plaintext = βNever trust a computer you canβt throw out a window. -Steve WozniakβΒ keyphrase = βIβll have you know that I stubbed my toe last week and only cried for 20 minutes.β
corpus = βWhen in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Natureβs God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.β
Β
Resulting ciphertextβΒ Β Β Β :β βDk5wQ 1Q4RW h yLCO4XnQ 8H4 yaEβ3 VpQH6 L4V a 6qGoJ6.β
-R3n5t 6J9GqIAβ
Β
Return value in $v0: 53β
Β
Return value in $v1: 14β
Β
Example #2:
Β
plaintext = βThe trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it. -Terry Pratchettβ
keyphrase = βWhatβs the difference between ignorance and apathy? I donβt know and I donβt care.β
Β
corpus = βCall me Ishmael. Some years ago β never mind how long precisely β having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation.β
Β
Resulting ciphertextβΒ Β Β Β Β Β Β Β Β Β :β βXjc 1UN4dDn 6xXj jW5vJk WJ ORcK GmKf, PI iO4TVn, mVβ
0jW3 RwQREy 6mDE xKVlV1 NJ iMGqLk aDPJk aJf 2U8uHk 2Q R40 2jlJkV xK lZ.
-3rUT8 RThYijc23β
Β
Return value in $v0: 111β
Β
Return value in $v1: 29β
Β
Example #3:
Β
plaintext = βIf debugging is the process of removing software bugs, then programming must be the process of putting them in. -Edsger Dijkstraβ
keyphrase = βWhat is the sum of 12 and 37? The answer, CLEARLY, is 49!β
corpus = βIt was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way β in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.β
Β
Resulting ciphertextβΒ Β Β Β Β Β Β Β Β Β Β :β βL7 e1iXTTAkT 9K MCu zFxsnGH x7 F2jxZEkT Gy7P0hDo iXTI,β
VCfk zFqTDhjj4kT jXKP in Mwm zFqsdKG q7 zXNOEkT VCnj Rk. -2eGTuD eAbcKSDtβ
Β
Return value in $v0: 105β
Β
Return value in $v1: 23β
Β
Β
Part 10: Decrypt Ciphertext that was Encrypted using a Homophonic Substitution Cipher
Β
int, int decrypt(string plaintext, string ciphertext, string keyphrase,Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β string corpus)
Β
This function decrypts a ciphertext message that was encrypted using the homophonic substitution cipher described earlier in the document. The decryption algorithm is very similar to the encryption algorithm. All arguments are assumed to be valid. The buffer for the ciphertext is guaranteed to be large enough to store the null-terminated plaintextβΒ Β Β Β Β Β Β Β Β Β Β . Note that the function returns two values. TheβΒ Β Β Β Β Β Β Β Β generated plaintext letters will all be in lowercase.
The function takes the following arguments, in this order:
- plaintextβ: an uninitialized buffer to store the decrypted ciphertext
- ciphertextβ: a βnon-emptyβ, null-terminated string to be decrypted using the homophonic substitution cipher
- keyphraseβ: a βnon-emptyβ, null-terminated keyphrase string used during the decryption process
- corpusβ: a βnon-emptyβ, null-terminated corpus string used during the decryption process
Β
The function implements the following algorithm:
- Call βto_lowercaseβ on βcorpusβ.
- Allocate at least 26 wordsβ worth of memory on the stack to temporarily store the βcountsβ array needed in the following step. Be sure to deallocate this memory later.
- Call βcount_lowercase_letters(counts, corpus)β.
- Allocate at least 27 bytes of memory on the stack to store the βlowercase_lettersβ string needed in the following step. Be sure to deallocate this memory later.
- Call βsort_alphabet_by_count(lowercase_letters, counts)β.
- Allocate at least 63 bytes of memory on the stack to temporarily store the plaintext_alphabetβ string needed in the following step. Be sure to deallocate this memory later.
- Call βgenerate_plaintext_alphabet(plaintext_alphabet, lowercase_letters)β.
- Allocate at least 63 bytes of memory on the stack to temporarily store the ciphertext_alphabetβ string needed in the following step. Be sure to deallocate this memory later.
- Call βgenerate_ciphertext_alphabet(ciphertext_alphabet, keyphrase)β.
- In a loop, decrypt each alphabetical character of βciphertextβ and write the decrypted character into βplaintextβ. Each βnon-alphanumericalβ character of βciphertextβ should simply be copied to βplaintextβ.
- Null-terminate the βplaintextβ
Β
Returns in $v0:
- The number of lowercase letters that were written into the βplaintextβ buffer during the decryption process.
Β
Returns in $v1:
- The number of non-letters that were written into the βplaintextβ buffer during the decryption process.
Β
Additional requirements:
- The function must not write any changes to main memory except as needed.
- The function must call the functions βto_lowercaseβ, βcount_lowercase_lettersβ, sort_alphabet_by_countβ, βgenerate_ciphertext_alphabetβ, generate_plaintext_alphabetβ, and βindex_ofβ.
Β
Example #1:
ciphertext = βDk5wQ 1Q4RW h yLCO4XnQ 8H4 yaEβ3 VpQH6 L4V a 6qGoJ6. -R3n5t 6J9GqIAβΒ keyphrase = βIβll have you know that I stubbed my toe last week and only cried for 20 minutes.β
corpus = βWhen in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Natureβs God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.β
Β
Resulting plaintextβ :β βnever trust a computer you canβt throw out a window.β
-steve wozniakβ
Β
Return value in $v0: 53β
Β
Return value in $v1: 14β
Β
Example #2:
Β
ciphertext = β βXjc 1UN4dDn 6xXj jW5vJk WJ ORcK GmKf, PI iO4TVn, mV 0jW3β
RwQREy 6mDE xKVlV1 NJ iMGqLk aDPJk aJf 2U8uHk 2Q R40 2jlJkV xK lZ. -3rUT8
RThYijc23β
keyphrase = βWhatβs the difference between ignorance and apathy? I donβt know and I donβt care.β
Β
corpus = βCall me Ishmael. Some years ago β never mind how long precisely β having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation.β
Β
Resulting plaintextβ :β βthe trouble with having an open mind, of course, is thatβΒ Β Β people will insist on coming along and trying to put things in it. -terry pratchettβ
Β
Return value in $v0: 111β
Β
Return value in $v1: 29β
Β
Example #3:
ciphertext = βL7 e1iXTTAkT 9K MCu zFxsnGH x7 F2jxZEkT Gy7P0hDo iXTI, VCfk zFqTDhjj4kT jXKP in Mwm zFqsdKG q7 zXNOEkT VCnj Rk. -2eGTuD eAbcKSDtβ
keyphrase = βWhat is the sum of 12 and 37? The answer, CLEARLY, is 49!β corpus = βIt was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way β in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.β
Β
Resulting plaintextβ :β βif debugging is the process of removing software bugs,βΒ Β Β Β Β Β then programming must be the process of putting them in. -edsger dijkstraβ
Β
Return value in $v0: 105β
Β
Return value in $v1: 23β




