Skip to content

Commit 5e625e7

Browse files
committed
Make MACs thread-local to avoid repeated reinstantiation/garbage collection.
1 parent bb9943f commit 5e625e7

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/main/java/com/eatthepath/otp/HmacOneTimePasswordGenerator.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public class HmacOneTimePasswordGenerator {
4242

4343
private final int modDivisor;
4444

45+
private final ThreadLocal<Mac> macThreadLocal;
46+
4547
/**
4648
* The default length, in decimal digits, for one-time passwords.
4749
*/
@@ -118,6 +120,16 @@ protected HmacOneTimePasswordGenerator(final int passwordLength, final String al
118120
// Our purpose here is just to throw an exception immediately if the algorithm is bogus.
119121
Mac.getInstance(algorithm);
120122
this.algorithm = algorithm;
123+
124+
this.macThreadLocal = ThreadLocal.withInitial(() -> {
125+
try {
126+
return Mac.getInstance(algorithm);
127+
} catch (final NoSuchAlgorithmException e) {
128+
// This should never happen; we just checked to make sure we could instantiate a MAC with this
129+
// algorithm, and if we made it this far, we know it worked.
130+
throw new RuntimeException(e);
131+
}
132+
});
121133
}
122134

123135
/**
@@ -132,15 +144,8 @@ protected HmacOneTimePasswordGenerator(final int passwordLength, final String al
132144
* @throws InvalidKeyException if the given key is inappropriate for initializing the {@link Mac} for this generator
133145
*/
134146
public int generateOneTimePassword(final Key key, final long counter) throws InvalidKeyException {
135-
final Mac mac;
136-
137-
try {
138-
mac = Mac.getInstance(this.algorithm);
139-
mac.init(key);
140-
} catch (final NoSuchAlgorithmException e) {
141-
// This should never happen since we verify that the algorithm is legit in the constructor.
142-
throw new RuntimeException(e);
143-
}
147+
final Mac mac = this.macThreadLocal.get();
148+
mac.init(key);
144149

145150
final ByteBuffer buffer = ByteBuffer.allocate(8);
146151
buffer.putLong(0, counter);

0 commit comments

Comments
 (0)