1
\$\begingroup\$

I have a program that:

  1. Takes a user specified string
  2. Creates password from the string and previous, current, and next day
  3. Encrypts the strings
  4. Chops some middle characters from the strings (needed to be shorter password)
  5. Returns a JSON object with 3 passwords

My main concern is that everything is almost repeated 3 times and there is a lot of string chopping and stitching. I believe the encryption methods are as short as they will get (not my methods). Any improvements to shorten the length and run time of the code would be great. Its run time has great importance because it is a REST API.

Controller:

public JSONObject getPasswordResults(@RequestParam String searchString) {
 // Final results of previous, current, and next passwords
 String previousResult = "";
 String result = "";
 String nextResult = "";
 try {
 // Previous and next day times, -1 is one day previous, 1 is one day in future
 long previousTime = serviceNowPasswordService.getTime(-1);
 long time = serviceNowPasswordService.getTime(0);
 long nextTime = serviceNowPasswordService.getTime(1);
 // Seeds
 String previousSeed = searchString + previousTime;
 String seed = searchString + time;
 String nextSeed = searchString + nextTime;
 System.out.println("Original: \"" + seed + "\"");
 // Encrypted password calls
 String previousEnc = serviceNowPasswordService.encrypt(previousSeed);
 String enc = serviceNowPasswordService.encrypt(seed);
 String nextEnc = serviceNowPasswordService.encrypt(nextSeed);
 System.out.println("Encrypted: \"" + enc.toUpperCase() + "\"");
 // Chopping passwords to fit length of oracle database requirements
 previousResult = previousEnc.toUpperCase();
 String previous_result_beg = previousResult.substring(0, 8);
 String previous_result_end = previousResult.substring(16, 32);
 previousResult = previous_result_beg + previous_result_end;
 result = enc.toUpperCase();
 String result_beg = result.substring(0, 8);
 String result_end = result.substring(16, 32);
 result = result_beg + result_end;
 nextResult = nextEnc.toUpperCase();
 String next_result_beg = nextResult.substring(0, 8);
 String next_result_end = nextResult.substring(16, 32);
 nextResult = next_result_beg + next_result_end;
 /*
 * Unused for now, maybe needed for future ambitions
 *
 String dec = serviceNowPasswordService.decrypt(enc);
 System.out.println("Decrypted: \"" + dec.toUpperCase() + "\"");
 if (dec.equals(original)) {
 System.out.println("Encryption ==> Decryption Successful");
 }
 */
 } catch (Exception e) {
 System.out.println("Error: " + e.toString());
 }
 // Create results as JSON array with object
 JSONObject obj = new JSONObject();
 obj.put("previousPassword", previousResult);
 obj.put("password", result);
 obj.put("nextPassword", nextResult);
 return obj;
}

Services:

public long getTime(int difference) {
 // Current time
 long time = System.currentTimeMillis();
 time = (time / 1000 / 60 / 60 / 24);
 time += difference;
 return time;
}
public String encrypt(String searchString) throws GeneralSecurityException, UnsupportedEncodingException {
 String hexKey = "GD6GTT56HKY4HGF6FH3JG9J5";
 //TripleDes3 encryptor = new TripleDes3(new String(Hex.decodeHex(hexKey.toCharArray())));
 try {
 TripleDes3(hexKey);
 } catch (Exception e) {
 System.out.println("Error: " + e.toString());
 }
 bytes = searchString.getBytes("ISO8859_15");
 bytes = Arrays.copyOf(bytes, ((bytes.length + 7) / 8) * 8);
 return new String(Hex.encodeHex(encryptB(bytes)));
}
public void TripleDes3(String encryptionKey) throws GeneralSecurityException, DecoderException {
 cipher = Cipher.getInstance("DESede/CBC/NoPadding");
 try {
 key = new SecretKeySpec(encryptionKey.getBytes("ISO8859_15"), "DESede");
 iv = new IvParameterSpec(Hex.decodeHex("0123456789abcdef".toCharArray()));
 } catch (UnsupportedEncodingException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
}
public byte[] encryptB(byte[] bytes) throws GeneralSecurityException {
 cipher.init(Cipher.ENCRYPT_MODE, (Key) key, iv);
 return cipher.doFinal(bytes);
}
Tolani
2,5017 gold badges31 silver badges49 bronze badges
asked Jul 19, 2016 at 12:43
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You can get rid of the repetition you already noticed by extracting the process into a separate method.

In the end your method might look like:

public JSONObject getPasswordResults(@RequestParam String searchString) {
 JSONObject obj = new JSONObject();
 obj.put("previousPassword", encryptWithTime(searchString, serviceNowPasswordService.getTime(-1)));
 obj.put("password", encryptWithTime(searchString, serviceNowPasswordService.getTime(0)));
 obj.put("nextPassword", encryptWithTime(searchString, serviceNowPasswordService.getTime(1)));
 return obj;
}

That's the simple-ish part. To make this work you need to extract the steps of you method into encryptWithTime:

public String encryptWithTime(String cleartext, long time) {
 try {
 String cryptext = serviceNowPasswordService.encrypt(cleartext + time).toUpperCase();
 } catch (Exception e) {
 e.printStackTrace(System.err);
 }
 return cryptext.substring(0,8) + cryptext.substring(16,32);
}

This is extremely dense code, information-wise. I removed a significant number of your intermediate variables. This may be unwise overall, because there is a lot going on at once in there.
This makes processing the code mentally a lot more challenging.

answered Jul 19, 2016 at 12:59
\$\endgroup\$
5
  • \$\begingroup\$ I like that, I don't mind the denseness, thats what commenting is for. \$\endgroup\$ Commented Jul 19, 2016 at 13:29
  • \$\begingroup\$ This may be a bit extreme, but I still think that if the code NEEDS a comment, it is either very complicated code or it has to be written differently. Otherwise, let the code speak for itself. For instance, is the // Seeds comment really necessary if variables are called previousSeed, seed and nextSeed? \$\endgroup\$ Commented Jul 20, 2016 at 9:12
  • \$\begingroup\$ @ChatterOne why not take that, take the other points you seem to have and write an answer with those? \$\endgroup\$ Commented Jul 20, 2016 at 12:07
  • \$\begingroup\$ @Vogel612 Because your answer looks good enough to me. I was just replying to theblindprophet and that was the only point that I had. \$\endgroup\$ Commented Jul 20, 2016 at 13:01
  • \$\begingroup\$ @ChatterOne there's nothing wrong with multiple answers on one question. I'm looking forward to your review :) \$\endgroup\$ Commented Jul 20, 2016 at 13:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.