Show notes for this video - Base62Encoder/Decoder written in non-functional Java.
Base62Encoder is written using FP and non FP in Go Lang, Java, Scala, Kotlin, JavaScript, TypeScript, Clojure, Rust and Python to demonstrate and discuss FP support in different languages.
#java #functionaljava #base62eoncoder_decoder
- How a URL Shortening Application Works
- Designing the Shortening URL system like Bit.ly, loading 6 billion clicks a month
- Base62 Encoder/Decoder written in Java, Scala, Clojure, Go, Rust, JavaScript, TypeScript, Kotlin, etc.
- First Video in Base62 language series 3rd Vlog video Show Notes
- Second Video in Base62 language (Java) series 4th Vlog video Show Notes
- Third Video in Base62 language (Scala) series 5th Vlog video Show Notes
- Fourth Video in Base62 language (Clojure) series 6th Vlog video Show notes
- Fifth Video in Base62 language (Python) series 7th Vlog video Show notes
- Sixth Video in Base62 language (JavaScript/TypeScript) series 8th Vlog video Show notes
- Seventh Video in Base62 language (Rust) series 9th Vlog video Show notes
- Eighth Video in Base62 language (Go Lang) series 10th Vlog video Show notes
package main.normal;
public class Base62Encoder {
public static void main(String[] args) {
final long id = 12345678910L;
final String strId = convertToEncodedString(id);
final long newId = convertToLong(strId);
System.out.printf("%d %s %d\n", id, strId, newId);
final String longURL = "https://www.somewebiste.com/dp/0201616165/?_encoding=UTF8&pd_rd_w=vwEcs&content-id=amzn1.sym.8cf3b8ef-6a74-45dc-9f0d-6409eb523603&pf_rd_p=8cf3b8ef-6a74-45dc-9f0d-6409eb523603&pf_rd_r=BQ0KD40K57XG761DBNBA&pd_rd_wg=DtkHk&pd_rd_r=f94b60b7-9080-4065-b77f-6377ec854d17&ref_=pd_gw_ci_mcx_mi";
final long urlId = Math.abs(longURL.hashCode()); //or save URL in DB and get ID from DB row.
final String shortHandle = convertToEncodedString(urlId);
System.out.printf("%d %s %d\n", urlId, shortHandle, convertToLong(shortHandle));
}
private static final char[] DIGITS = {
//0 1 2 3 4 5 6 7 8 9
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
//10 11 12 13 14 15 16 17 18 19 20 21
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
//22 23 24 25 26 27 28 29 30 31 32 33 34 35
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
// 36 37 38 39 40 41 42 43 44 45 46 47
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', //Easy to add more characters if not using lookup tables.
// 48 49 50 51 52 53 54 55 56 57 58 59 60 61 // 62 63, 64
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', // '*', '@', '$'
};
public static long convertToLong(String strId) {
return convertToLong(strId.toCharArray());
}
public static String convertToEncodedString(final long id) {
final StringBuilder builder = new StringBuilder();
int placeHolder = findStartBucket(id);
long bucketValue;
long acc = id;
int digitIndex;
while (placeHolder > 1) {
//bucketValue = buckets[index];
bucketValue = powDigitsBase(placeHolder);
digitIndex = (int) (acc / bucketValue);
acc = acc - (bucketValue * digitIndex);
appendSafe(builder, digitIndex);
placeHolder--;
}
//bucketValue = buckets[1];
bucketValue = powDigitsBase(1);
digitIndex = (int) (acc / bucketValue);
acc = acc - (bucketValue * digitIndex);
appendSafe(builder, digitIndex);
//Put the remainder in the ones column
digitIndex = (int) (acc % bucketValue);
builder.append(DIGITS[digitIndex]);
return builder.toString();
}
private static long convertToLong(char[] chars) {
long acc = 0;
int position = 0;
for (int index = chars.length - 1; index > -1; index--) {
char c = chars[index];
long value = computeValue(c, position);
acc += value;
position++;
}
return acc;
}
private static int findIndexOfDigitInTable(char c) {
for (int i = 0; i < DIGITS.length; i++) {
char digit = DIGITS[i];
if (c == digit) {
return i;
}
}
throw new IllegalStateException("Unknown char #" + c + "#");
}
private static long computeValue(char c, int position) {
final int digitIndex = findIndexOfDigitInTable(c);
final long multiplier = powDigitsBase(position);
//final long multiplier = buckets[position];
return digitIndex * multiplier;
}
private static void appendSafe(StringBuilder builder, int digitIndex) {
if (digitIndex != 0) {
builder.append(DIGITS[digitIndex]);
} else {
if (builder.length() > 0) {
builder.append(DIGITS[digitIndex]);
}
}
}
private static long powDigitsBase( final long exponent) {
return doPow(exponent, DIGITS.length);
}
private static long doPow( final long exponent, final long base) {
long result = 1;
long exp = exponent;
while (exp != 0) {
result *= base;
--exp;
}
return result;
}
private static int findStartBucket(long value) {
for (int i = 0; i < 15; i++) {
if (value < powDigitsBase(i)) {
return i-1;
}
}
return 0;
}
}