Question
Skills covered in this lab that were reviewed in class: SHA256 Hashing Multithreading TIP : Remember, don't be overwhelmed by all the details. Simply focus
Skills covered in this lab that were reviewed in class:
SHA256 Hashing
Multithreading
TIP
: Remember, don't be overwhelmed by all the details. Simply focus on one line at a time as the
instructions walk you through the creation of the app.
1. SUMMARY
The user first enters in the merkle root of four words the user will try to give to the merkle thread...
this merkle root can be manually figured out by the user from the "NOTE" desctiption on the top of
page 2.
Then a multithreaded portion of the app allows user submission of Strings on the main thread, and
each of those Strings is grabbed by a Merkle or Rogue background thread depending on the users
timing.
If the Merkle thread gets enough words (4), then it will create a merkle tree and produce a merkle
root string and if it matches the initial merkle root entered by the user, the user wins ... if it doesnt
match the user loses.
Meanwhile, every word the rogue thread gets is a strike. 3 strikes and the user loses.
The two background threads will sleep a random number of seconds which challenges the user to
time their entry just right so that the Merkle thread gets the word.
A third Monitor thread in the background will check on progress and end the app once lost or won.
So it's just a simple game to allow you to get some coding experience with multithreading and merkle
roots.
2. DETAILS
a.
Youre creating a console app.
b. Remember that if you prompt the user for input and background threads are printing stuff to screen,
it doesnt affect your typing and hitting return... even if your typing is mixed up with all the printing
statements.
c.
Classes
i. MerkleManager_Test
1. Will have main method and will instantiate instance of MerkleManager and call manage
function... that's it.
ii. MerkleManager
1. Instance variables:
a.
Public & static & volatile String for Users entered word.
b. Public & static String for user entered expected merkle root.
c.
Public & static String for merkle root set to null.
d. Public & static int for strikes set to 0.
2. Method: A public "manage" method and this will be called by the MerkleManager_Test class's
main method.
a.
No inputs or outputs.
b. Use Util class (that youll create later on below) to prompt user for the expected merkle
root after theyve entered four words.
i. Put user entered text into the instance variable to hold for end of game comparison.
ii.
NOTE
: Use
https://www.xorbin.com/tools/sha256-hash-calculator to figure out merkle
root of the four words you expect to use just like we do in the code:
1. EXAMPLE:
H6: Merkle root
/ \
H4 H5
/ \ / \
H0 H1 H2 H3
| | | |
word1 word2 word3 word4
a.
if your words were word1, word2, word3, word4, then you would
enter word1 into the above web page and get the hash (H0),
b. Then do the same with the others.
c.
Then combine each pair of hashes, so the hash of word1 (H0) together with
the hash of word2 (H1), and get the hash of that long string (H4). Youll do
that twice, once for the first two (H0 & H1) and once for the second two (H2 &
H3). So you now have H4 & H5.
d. Finally, then combine those resulting two hashes (H4 & H5) into one string in
the web page entry to produce another hash this is your merkle root hash.
e. Copy this merkle root from the web page and paste into your user entry when
prompted in the console.
c.
Start 3 separate threads: Instantiate and start new threads for...
i. MerkleThread, RogueThead, MonitorThread.
d. Begin UI Menu Loop:
i. Just use while(true) to make an eternal loop (because the monitor will eventually close
the app).
ii. Ask user for a word and put it into instance variable for users word.
3. Method: A public & static & synchronized method called grabWord.
a.
No inputs but returns a String.
b. Puts instance variable of users word into a temp String variable and then makes the
instance variable null.
c.
Then returns the temp variable.
iii. MerkleThread
1. This class must implement Runnable.
2. Instance variables:
a.
Public & static & volatile ArrayList
i. Example:
1. public static volatile ArrayList
lstWords
;
b. Private int called
iMerkleTreeInputs
for how many words to wait for before creating a
merkle tree.
i. Set it equal to 4.
3. Method: A public run method that is triggered when start is called from MerkleManager.
a.
No inputs or outputs.
b. Instantiate a Util class object (Util class is defined lower down).
c.
Instantiate the ArrayList instance variable.
i. Example:
1. lstWords = new ArrayList();
ii. Create a neverending while loop like this:
1. while(true){...
2. In loop, do all the following:
a.
Call sleepRandomTime on util variable.
b. Cal grabWord on MerkleManager.
i. Example of how to call static method:
String sNewWord = MerkleManager.grabWord();
c.
Then if sNewWord is not null:
i. Print out that Merkle grabbed a word.
ii. Add word to lstWords like this: lstWords.add(sNewWord);
iii. Check if lstWords.size() is equal to iMerkleTreeInputs.
iv. And if true, then set MerkleManager.sMerkleRoot to the merkle root
generated by the getMerkleRoot method on util class.
iv. RogueThread
1. This class must implement Runnable.
2. Method: A public run method.
a.
No inputs or outputs.
b. Instantiate a Util object.
c.
Create a neverending loop again just like youve done before.
i. Inside loop, do all the following:
1. Call sleepRandomTime on util variable.
2. Call grabWord similar to how described in MerkleThread.
3. If sNewWord is not null:
a.
Increase iStrikes static variable on MerkleManager by 1.
b. Print out to screen that rogue grabbed a word and mention STRIKE!
v. MonitorThread
1. Method: run method just as in the other Thread classes.
a.
Create endless loop as youve done above.
i. If MerkleManager.sMerkleRoot is not null then...
1. If the above merkle root equals the initial user-entered merkle root (which you
can access the same way as above since theyre both static on MerkleManager):
a.
Then print out You win: followed by the merkle root (which is the above
static variable on MerkleManager) and exit the app.
2. Else if theyre not equal, then tell the user and that the user lost and exit the
app.
a.
To exit:
System.exit(0);
ii. Else if MerkleManager.iStrikes equals 3 then print out 3 strikes: you lost! or
something like that and exit the app as shown in line of code above.
iii. After the if-else statement, then call sleep on util object and sleep for 1 second.
1. (if you dont do this, the endless loop never allows updates on that thread to see
MerkleManagers changing values.)
vi. MerkleNode
1. Three instance variables:
a.
sHash is a String.
b. oLeft is a MerkleNode.
c.
oRight is a MerkleNode.
vii. Util
1. This will have helper functions that all the classes can use.
2. Method: Public method called getMerkleRoot.
a.
Inputs:
i. ArrayList
b. Description:
i. Not much description here since we did this in class.
ii. Creates 7 MerkleNode objects and slowly builds tree to get merkle root.
3. Method: Private method called populateMerkleNode.
a.
Inputs:
i. Three MerkleNode types: first is to be populated, second is to be the left node of the
first node, and third is to be the right node of the first node.
ii. Desctiption:
iii. Not much description because was reviewed in class.
1. Basically sets hash, left, and right node values.
4. Method: generateHash
a.
NOTE
: This method is given to you on Canvas in this weeks module and in class.
5. Method: public method called promptUser.
a.
Input: String of question to ask user.
b. Output: String answer from user.
c.
Description: Use JOptionPane class to get user input so that the user doesnt have to type
while all the other text is being printed out.
i. Code provided here for getting user input in case you havent used JOptionPane
before:
//at top of file to allow use of JOptionPane:
import javax.swing.JOptionPane;
//inside class
public String promptUser(String sQuestion){
JOptionPane oQuestion = new JOptionPane();
String sAnswer = oQuestion.showInputDialog(sQuestion);
return sAnswer;
}
HashCodeFunction:
Imports required for hash function:
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
...
Function to go inside of a Util class:
public synchronized String generateHash(String sOriginal){
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] btEncodedhash = digest.digest(
sOriginal.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < btEncodedhash.length; i++) {
sb.append(Integer.toString((btEncodedhash[i] & 0xff) + 0x100,
16).substring(1));
}
return sb.toString();
}
catch(Exception ex){
System.out.println("Error generating hash: " + ex.getMessage());
return null;
}
}
sleepRandomTime_method:
// Here is the import for the random number generator to go at top of your
class...
import java.security.SecureRandom;
// and here is the method...
public void sleepRandomTime(String sThreadName){
// Gets random number between 0 and 5 and then adds 3, meaning
between 3 and 8 now.
int iSleepTime = new SecureRandom().nextInt(5) + 3;
System.out.println(sThreadName + " sleeping for " + iSleepTime + "
seconds.");
sleep(iSleepTime);
}
Please use Intellj and mark each Java file to me. Thank you.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started