in src/main/java/org/apache/commons/text/AlphabetConverter.java [129:222]
public static AlphabetConverter createConverter(
final Integer[] original,
final Integer[] encoding,
final Integer[] doNotEncode) {
final Set<Integer> originalCopy = new LinkedHashSet<>(Arrays.asList(original));
final Set<Integer> encodingCopy = new LinkedHashSet<>(Arrays.asList(encoding));
final Set<Integer> doNotEncodeCopy = new LinkedHashSet<>(Arrays.asList(doNotEncode));
final Map<Integer, String> originalToEncoded = new LinkedHashMap<>();
final Map<String, String> encodedToOriginal = new LinkedHashMap<>();
final Map<Integer, String> doNotEncodeMap = new HashMap<>();
final int encodedLetterLength;
for (final int i : doNotEncodeCopy) {
if (!originalCopy.contains(i)) {
throw new IllegalArgumentException(
"Can not use 'do not encode' list because original "
+ "alphabet does not contain '"
+ codePointToString(i) + "'");
}
if (!encodingCopy.contains(i)) {
throw new IllegalArgumentException(
"Can not use 'do not encode' list because encoding alphabet does not contain '"
+ codePointToString(i) + "'");
}
doNotEncodeMap.put(i, codePointToString(i));
}
if (encodingCopy.size() >= originalCopy.size()) {
encodedLetterLength = 1;
final Iterator<Integer> it = encodingCopy.iterator();
for (final int originalLetter : originalCopy) {
final String originalLetterAsString = codePointToString(originalLetter);
if (doNotEncodeMap.containsKey(originalLetter)) {
originalToEncoded.put(originalLetter, originalLetterAsString);
encodedToOriginal.put(originalLetterAsString, originalLetterAsString);
} else {
Integer next = it.next();
while (doNotEncodeCopy.contains(next)) {
next = it.next();
}
final String encodedLetter = codePointToString(next);
originalToEncoded.put(originalLetter, encodedLetter);
encodedToOriginal.put(encodedLetter, originalLetterAsString);
}
}
return new AlphabetConverter(originalToEncoded, encodedToOriginal, encodedLetterLength);
}
if (encodingCopy.size() - doNotEncodeCopy.size() < 2) {
throw new IllegalArgumentException(
"Must have at least two encoding characters (excluding "
+ "those in the 'do not encode' list), but has "
+ (encodingCopy.size() - doNotEncodeCopy.size()));
}
// we start with one which is our minimum, and because we do the
// first division outside the loop
int lettersSoFar = 1;
// the first division takes into account that the doNotEncode
// letters can't be in the leftmost place
int lettersLeft = (originalCopy.size() - doNotEncodeCopy.size())
/ (encodingCopy.size() - doNotEncodeCopy.size());
while (lettersLeft / encodingCopy.size() >= 1) {
lettersLeft /= encodingCopy.size();
lettersSoFar++;
}
encodedLetterLength = lettersSoFar + 1;
final AlphabetConverter ac =
new AlphabetConverter(originalToEncoded,
encodedToOriginal,
encodedLetterLength);
ac.addSingleEncoding(encodedLetterLength,
StringUtils.EMPTY,
encodingCopy,
originalCopy.iterator(),
doNotEncodeMap);
return ac;
}