Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- public class TKCalculateUtils {
- public static long hexCharAsNumber(char c) {
- if (c >= 'a') {
- return c - 87;
- } else {
- return Long.valueOf(String.valueOf(c));
- }
- }
- public static long normalizeHash(long encondindRound2) {
- if (encondindRound2 < 0) {
- encondindRound2 = (encondindRound2 & 0x7fffffffL) + 0x80000000L;
- }
- return encondindRound2 % 1000000L;
- }
- public static List<Long> transformQuery(String query) {
- List<Long> result = new ArrayList<>();
- for (int i = 0; i < query.length(); i++) {
- char c = query.charAt(i);
- if (c < 128) {
- result.add((long) c); // 0{l[6-0]}
- } else if (c < 2048) {
- result.add(c >> 6 | 0xC0L); // 110{l[10-6]}
- result.add(c & 0x3F | 0x80L); // 10{l[5-0]}
- } else if (0xD800L == (c & 0xFC00L) && c + 1 < query.length() && 0xDC00L == (query.charAt(i + 1) & 0xFC00L)) {
- // that's pretty rare... (avoid ovf?)
- c = (char) ((1 << 16) + ((c & 0x03FF) << 10) + (query.charAt(++i) & 0x03FF));
- result.add(c >> 18 | 0xF0L); // 111100{l[9-8*]}
- result.add(c >> 12 & 0x3FL | 0x80L); // 10{l[7*-2]}
- result.add(c & 0x3FL | 0x80L); // 10{(l+1)[5-0]}
- } else {
- result.add(c >> 12 | 0xE0L); // 1110{l[15-12]}
- result.add(c >> 6 & 0x3FL | 0x80L); // 10{l[11-6]}
- result.add(c & 0x3FL | 0x80L); // 10{l[5-0]}
- }
- }
- return result;
- }
- public static long shiftLeftOrRightThenSumOrXor(List<String> opArray, long num) {
- for (String opString : opArray) {
- char op1 = opString.charAt(1); // '+' | '-' ~ SUM | XOR
- char op2 = opString.charAt(0); // '+' | '^' ~ SLL | SRL
- char xd = opString.charAt(2); // [0-9a-f]
- long shiftAmount = hexCharAsNumber(xd);
- long mask = (op1 == '+') ? num >>> shiftAmount : num << shiftAmount;
- num = (op2 == '+') ? (num + mask & 0xffffffffL) : (num ^ mask);
- }
- return num;
- }
- /*
- / EXAMPLE:
- /
- / INPUT: query: 'hola', windowTkk: '409837.2120040981'
- / OUTPUT: '70528.480109'
- /
- */
- public static String calcHash(String query, String windowTkk) {
- // STEP 1: spread the the query char codes on a byte-array, 1-3 bytes per char
- List<Long> bytesArray = transformQuery(query);
- // STEP 2: starting with TKK index, add the array from last step one-by-one, and do 2 rounds of shift+add/xor
- String[] d = windowTkk.split("\\.");
- long tkkIndex = Long.valueOf(d[0]);
- long tkkKey = Long.valueOf(d[1]);
- long acc = tkkIndex;
- for (Long current : bytesArray) {
- acc += current;
- acc = shiftLeftOrRightThenSumOrXor(Arrays.asList("+-a", "^+6"), acc);
- }
- long encondingRound1 = acc;
- // STEP 3: apply 3 rounds of shift+add/xor and XOR with they TKK key
- long encondingRound2 = shiftLeftOrRightThenSumOrXor(Arrays.asList("+-3", "^+b", "+-f"), encondingRound1) ^ tkkKey;
- // STEP 4: Normalize to 2s complement & format
- long normalizedResult = normalizeHash(encondingRound2);
- return normalizedResult + "." + (normalizedResult ^ tkkIndex);
- }
- }
Add Comment
Please, Sign In to add comment