If you are open to using a third party library, the following solution works using Eclipse Collections:
MutableList<String> decryptedPasswordInPairs = Lists.mutable.with("A2")
.collectWith((oddPair, A5) ->
CharAdapter.adapt(oddPair)
.injectIntoWithIndex(
ByteLists.mutable.empty(),
(bytes, character, index) ->
bytes.with((byte) (character ^ A5.charAt(index % A5.length()))))
.makeString(""), "A5");
decryptedPasswordInPairs.each(System.out::println);
I used the following imports:
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.factory.primitive.ByteLists;
import org.eclipse.collections.impl.string.immutable.CharAdapter;
By using the primitive ByteList available in Eclipse Collections, I was able to avoid boxing. The method makeString which is available on ByteList allows you to control the separator. Passing in an empty String gets rid of the comma that you get using toString on a List. The class CharAdapter provides a set of char based protocols around String including the method I used here named injectIntoWithIndex.
The code can also be broken into smaller steps to make it slightly less dense and potentially easier to read.
MutableList<String> decryptedPasswordInPairs = Lists.mutable.with("A2")
.collect(CharAdapter::adapt)
.collectWith((oddPair, A5) ->
oddPair.injectIntoWithIndex(
ByteLists.mutable.empty(),
(bytes, character, index) ->
bytes.with((byte) (character ^ A5.charAt(index % A5.length())))), "A5")
.collectWith(ByteList::makeString, "");
decryptedPasswordInPairs.each(System.out::println);
Note: I am a committer for Eclipse Collections.