package org.nextprot.api.commons.utils;
import com.google.common.base.Preconditions;
import java.util.Arrays;
/**
* Code and decode 36-base 8-length string in the interval of longs [0:36^8[
*
* Created by fnikitin on 11/03/15.
*/
public class Base36Codec {
private static final long LOWER_RANGE = 0;
private static final long UPPER_RANGE = 2_821_109_900_000L; // 36^8
private static final String BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private Base36Codec() {
throw new IllegalAccessError("Utility class not meant to be instantiated");
}
/**
* @return the minimum included long
*/
public static long getLowerBound() {
return LOWER_RANGE;
}
/**
* @return the maximum excluded long
*/
public static long getUpperBound() {
return UPPER_RANGE;
}
/**
* Encode long in a base-36 string.
*
* @param value the long value to encode
* @return base-36 string
* @throws IndexOutOfBoundsException if value not in range [0, 2_821_109_900_000[
*/
public static String encodeBase36(final long value) {
if (value < 0 || value >= UPPER_RANGE) {
throw new IndexOutOfBoundsException("cannot encode " + value + ": long out of bound (valid range: [0, 2_821_109_900_000[)");
}
char[] buffer = new char[8];
Arrays.fill(buffer, '0');
int i=7;
long tmp = value;
while(tmp > 0 && i>=0) {
long remainder = tmp % 36;
buffer[i] = BASE36.charAt((int)remainder);
tmp = tmp/36;
i--;
}
return String.copyValueOf(buffer);
}
/**
* Decode a base-36 string in long
*
* @param base36String the string to decode in long
* @return the decoded long
* @throws java.lang.IllegalArgumentException if base36String length is too long (> 8)
* @throws NumberFormatException if not a base-36 encoded string
* @throws IndexOutOfBoundsException if the decoded long is out of range [0, 2_821_109_900_000[
*/
public static long decodeBase36(String base36String) {
Preconditions.checkNotNull(base36String);
Preconditions.checkArgument(base36String.length()<=8);
long decodedLong = Long.parseLong(base36String, 36);
if(decodedLong < 0 || decodedLong >= UPPER_RANGE) {
throw new IndexOutOfBoundsException("cannot decode " + decodedLong + ": long out of bound (valid range: [0, 2_821_109_900_000[)");
}
return decodedLong;
}
}