Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 6
The implementation of HashSequencer and its base class -- BaseSequencer -- is worth reviewing, because it's where the core of the Lamport algorithm is implemented. Listing 5 shows the code for
these classes.
package com.opensolutionspace.otp.lib;
import java.util.*;
import java.security.*;
import java.io.UnsupportedEncodingException;
import java.math.*;
/**
* The is the only concrete implementor of PassKeySequencer
* in the com.opensolutionspace.otp.lib package.
* Others can be found in the com.opensolutionspace.otp.poc package.
* Sequence is based on starting with a reasonably unique seed
* value and making each successor value the MD5-hash value of its
* predecessor ...
*
* @author lji
* 02/07/2009
*/
public class HashSequencer extends BaseSequencer implements PassKeySequencer {
protected String genSeed() {
return this.getClass().getName() + new Date().getTime();
}
public String encode(String value) {
String rval = "";
try {
rval = genMD5(value);
}
catch (NoSuchAlgorithmException ex) {
System.err.println("encode():" + ex);
return rval;
}
catch (UnsupportedEncodingException ex) {
System.err.println("encode():" + ex);
return rval;
}
return rval;
}
protected String genMD5(String value)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(value.getBytes(), 0, value.length());
return "" + new BigInteger(1, md.digest()).toString(16);
}
/*
NOTE: BaseSequence provides
implementation of nextValue() & genValues(...) methods
*/
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package com.opensolutionspace.otp.lib;
import java.util.*;
/**
* 02/02/2009
* Convenience base Sequencer Class - carries data structures and
* sequence value generation and maintenance logic that apply to all/most PassKeySequencer implementors.
* Concrete classes that implement PassKeySequencer would be well served
* by extending this base class and modifying/extending behavior as needed.
*
* @author lji
*/
public abstract class BaseSequencer {
protected int maxValues = PassKeySequencer.DEFUALT_MAX_VALUES;
protected Stack<String> passwordLifo;
protected abstract String genSeed();
public abstract String encode (String value);
protected String nextValue(String value) {
return encode(value);
}
public BaseSequencer() {
passwordLifo = new Stack<String>();
}
public BaseSequencer(int n) {
maxValues = n;
passwordLifo = new Stack<String>();
}
public String nextValue() {
return passwordLifo.pop();
}
public void genValues(int n) {
passwordLifo.removeAllElements();
String value = genSeed();
for (int i=0; i < n ; i++) {
value = nextValue(value);
passwordLifo.add(value);
}
}
public void genValues() {
genValues(maxValues);
}
}
The SimpleSequencer class, shown in Listing 6, represents an alternative sequence algorithm.
package com.opensolutionspace.otp.poc;
import java.util.*;
import com.opensolutionspace.otp.lib.BaseSequencer;
import com.opensolutionspace.otp.lib.PassKeySequencer;
/**
* 02/10/2009
*
* This sequencer produces a sequence of numbers that starts with
* "18" and goes onto generate a series of numbers that follows
* this logic - add 3 - if the resulting numbers contain a 3,
* replace it with a 4.
* @author lji
*/
public class SimpleSequencer
extends BaseSequencer implements PassKeySequencer {
public String encode(String value) {
/**
* Change to add 3, if result contains "3"
* change that digit to "4" ...
*/
int ival = this.seqToInt(value);
ival = ival += 3;
String sval = "" + ival;
return sval.replaceAll("3", "4");
}
protected String genSeed() {
return "18";
}
private int seqToInt(String seq) {
int ival;
try {
ival = Integer.parseInt(seq);
}
catch(NumberFormatException ex) {
ival = 90890707;
}
return ival;
}
}
Notice that the required coding here is limited to two methods: genSeed(), which is an abstract method defined in its superclass, and encode(), a method defined in the PassKeySequencer interface that implements the sequence algorithm.