private String decrypt(String key) { if (!isJuniper9CipherText(key)) { throw new BatfishException("Invalid Juniper $9$ ciphertext: \"" + key + "\""); } String[] chars = new String[] {key.substring("$9$".length())}; char first = nibble(chars, 1).charAt(0); nibble(chars, _characterFamilyReverseIndexMap.get(first)); char prev = first; StringBuilder decrypted = new StringBuilder(); while (chars[0].length() > 0) { List<Integer> decode = _codeMatrix.get(decrypted.length() % _codeMatrix.size()); int len = decode.size(); char[] nibbleChars = new char[len]; nibble(chars, len).getChars(0, len, nibbleChars, 0); List<Integer> gaps = new ArrayList<>(); for (int i = 0; i < len; i++) { char nibbleChar = nibbleChars[i]; int g = gap(prev, nibbleChar); prev = nibbleChar; gaps.add(g); } char newChar = gapDecode(gaps, decode); decrypted.append(newChar); } return decrypted.toString(); }