/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zeppelin.notebook.utility;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Generate Tiny ID.
*/
public class IdHashes {
private static final char[] DICTIONARY = new char[] {'1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z'};
/**
* encodes the given string into the base of the dictionary provided in the constructor.
*
* @param value the number to encode.
* @return the encoded string.
*/
private static String encode(Long value) {
List<Character> result = new ArrayList<>();
BigInteger base = new BigInteger("" + DICTIONARY.length);
int exponent = 1;
BigInteger remaining = new BigInteger(value.toString());
while (true) {
BigInteger a = base.pow(exponent); // 16^1 = 16
BigInteger b = remaining.mod(a); // 119 % 16 = 7 | 112 % 256 = 112
BigInteger c = base.pow(exponent - 1);
BigInteger d = b.divide(c);
// if d > dictionary.length, we have a problem. but BigInteger doesnt have
// a greater than method :-( hope for the best. theoretically, d is always
// an index of the dictionary!
result.add(DICTIONARY[d.intValue()]);
remaining = remaining.subtract(b); // 119 - 7 = 112 | 112 - 112 = 0
// finished?
if (remaining.equals(BigInteger.ZERO)) {
break;
}
exponent++;
}
// need to reverse it, since the start of the list contains the least significant values
StringBuffer sb = new StringBuffer();
for (int i = result.size() - 1; i >= 0; i--) {
sb.append(result.get(i));
}
return sb.toString();
}
public static String generateId() {
return encode(System.currentTimeMillis() + new Random().nextInt());
}
}