Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 4x 4x 4x 4x 36x 50x 50x 1x 49x 1850x 1850x 1850x 49x 41x 41x 41x 41x 41x 41x 41x 12x 4x 8x 8x 37x 1x 36x 36x 166x 4x 162x 162x 162x 36x 32x 28x 36x 190x 36x 7x 5x 2x 2x 2x 2x 4x 4x 4x 4x 4x | import emojiTable from './generated/table'; import type { EmojiHasher, EmojiTable, Options } from './types'; class EmojiHasherSingletone implements EmojiHasher { table: EmojiTable; defaultOptions: Options; maxBase: number; constructor() { this.table = emojiTable as EmojiTable; const base = Object.keys(this.table).length; this.maxBase = base; this.defaultOptions = { base }; } getHash(input: string, options?: Options): string { return this.transformBinary(this.getBitwise(input), options); } /** * @see {@link http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/} */ getBitwise(str: string): number { let hash = 0; if (str.length == 0) { return hash; } for (let i = 0; i < str.length; i++) { const ch = str.charCodeAt(i); hash = (hash << 5) - hash + ch; hash = hash & hash; // Convert to 32bit integer } return hash; } transformBinary(input: number, options?: Options): string { const stack = []; const sign = input < 0 ? this.table[0] : ''; const { base, length } = options ?? this.defaultOptions; let num; let result = ''; let expectedLength = 0; let shouldUseLength = false; if (length !== null && length !== undefined && !Number.isNaN(length)) { if (length <= 0) { throw new Error('property `length` must equals at least 1'); } shouldUseLength = true; expectedLength = length - (sign ? 1 : 0); } if (base > this.maxBase) { throw new Error(`'base' mustn't be bigger than ${this.maxBase}`); } input = Math.abs(input); while (input >= base) { if (shouldUseLength && stack.length >= expectedLength) { break; } num = input % base; input = Math.floor(input / base); stack.push(this.table[num]); } if (input > 0 && input < base) { if (!shouldUseLength || (shouldUseLength && stack.length < expectedLength)) { stack.push(this.table[input]); } } for (let i = stack.length - 1; i >= 0; i--) { result += stack[i]; } return sign + result; } useTable(newTable: EmojiTable): void { if (!newTable || typeof newTable !== 'object' || !Object.keys(newTable).length) { throw new Error('newTable must contains dictionary'); } this.table = newTable; const base = Object.keys(this.table).length; this.maxBase = base; this.defaultOptions = { ...this.defaultOptions, base }; } } const instance = new EmojiHasherSingletone(); export const getHash = instance.getHash.bind(instance); export const useTable = instance.useTable.bind(instance); export const getBitwise = instance.getBitwise.bind(instance); export const transformBinary = instance.transformBinary.bind(instance); export default instance; |