All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.codeflush.baseencoder.SimpleBaseEncoding Maven / Gradle / Ivy

The newest version!
package dev.codeflush.baseencoder;

public class SimpleBaseEncoding implements BaseEncoding {

    private static final int LOOKUP_FACTOR = 100;

    private final char[] chars;
    private final int[][] indexLookup;
    private final int bitBlockSize;

    public SimpleBaseEncoding(String str) {
        this(str.toCharArray());
    }

    public SimpleBaseEncoding(char[] chars) {
        if (chars.length < 2 || !isPowerOfTwo(chars.length)) {
            throw new IllegalArgumentException("chars length must be a power of 2");
        } else if (containsDuplicates(chars)) {
            throw new IllegalArgumentException("every character must be unique");
        }

        this.chars = chars;
        this.indexLookup = buildLookup(chars);
        this.bitBlockSize = 31 - Integer.numberOfLeadingZeros(chars.length);
    }

    @Override
    public int bitBlockSize() {
        return this.bitBlockSize;
    }

    @Override
    public char get(int index) {
        return this.chars[index];
    }

    @Override
    public int index(char c) {
        return this.indexLookup[c / LOOKUP_FACTOR][c % LOOKUP_FACTOR];
    }

    private static boolean isPowerOfTwo(int number) {
        return number > 0 && ((number & (number - 1)) == 0);
    }

    private static boolean containsDuplicates(char[] chars) {
        for (int i = 0; i < chars.length; i++) {
            for (int j = i + 1; j < chars.length; j++) {
                if (chars[i] == chars[j]) {
                    return true;
                }
            }
        }

        return false;
    }

    private static int[][] buildLookup(char[] chars) {
        final int[][] lookup = new int[(Character.MAX_VALUE / LOOKUP_FACTOR) + 1][];

        for (int i = 0; i < chars.length; i++) {
            final char c = chars[i];
            int[] innerLookup = lookup[c / LOOKUP_FACTOR];

            if (innerLookup == null) {
                innerLookup = new int[LOOKUP_FACTOR];
                lookup[c / LOOKUP_FACTOR] = innerLookup;
            }

            innerLookup[c % LOOKUP_FACTOR] = i;
        }

        return lookup;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy