1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | const RADIX = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ-0987654321_abcdefghijklmnopqrstuvwxyz';
|
21 | const BASE_TIME = 1456931443188;
|
22 |
|
23 | class Tokenizer {
|
24 |
|
25 | constructor (salt) {
|
26 | let validSalt = (salt && (typeof salt === 'string') && salt.length > 0);
|
27 | this.radix = (validSalt && salt) || RADIX;
|
28 | this.baseTime = 1456931443188;
|
29 | }
|
30 |
|
31 | generate (size) {
|
32 | let key = '';
|
33 | let len = this.radix.length;
|
34 | while ( size -- ) {
|
35 | let rnd = Tokenizer.rand(len);
|
36 | key += this.radix[rnd];
|
37 | }
|
38 | return key;
|
39 | }
|
40 |
|
41 | static rand (max = 10) {
|
42 | return Math.floor(Math.random() * max)
|
43 | }
|
44 |
|
45 | static toInt (encoded, base, chars) {
|
46 | let output = 0;
|
47 | let length = (encoded = encoded.split('')).length;
|
48 | let pos = 0;
|
49 |
|
50 | if (base > (chars = (chars || RADIX)).length || base < 2) {
|
51 | return NaN;
|
52 | }
|
53 |
|
54 | while (length--) {
|
55 | output += chars.indexOf(encoded[pos++]) * Math.pow(base, length);
|
56 | }
|
57 |
|
58 | return output;
|
59 | }
|
60 |
|
61 | static toBase (number, base, chars) {
|
62 |
|
63 | var output = "";
|
64 |
|
65 | if (base > (chars = (chars || RADIX).split('')).length || base < 2) {
|
66 | return '';
|
67 | }
|
68 |
|
69 | while (number) {
|
70 | output = chars[number % base] + output;
|
71 | number = Math.floor(number / base);
|
72 | }
|
73 |
|
74 | return output;
|
75 | }
|
76 |
|
77 | }
|
78 |
|
79 | module.exports = {
|
80 |
|
81 | Tokenizer,
|
82 |
|
83 | timeCoded (base) {
|
84 | base = base || RADIX;
|
85 | return Tokenizer.toBase(new Date().getTime() - BASE_TIME, base.length, base ) + ':' + module.exports.generate(4);
|
86 | },
|
87 |
|
88 | timeDecoded (str, base) {
|
89 | base = base || RADIX;
|
90 | str = str.split(':')[0];
|
91 | return new Date(Tokenizer.toInt(str, base.length, base ) + BASE_TIME);
|
92 | },
|
93 |
|
94 | generate : (() => {
|
95 | let defaultTokenizer = new Tokenizer();
|
96 | return defaultTokenizer.generate.bind(defaultTokenizer);
|
97 | })(),
|
98 |
|
99 | radixes : {
|
100 | '62' : RADIX.replace(/-|_/g, ''),
|
101 | '64' : RADIX,
|
102 | '74' : RADIX + '!@#$%^&*()+=',
|
103 | '84' : RADIX + '!@#$%^&*()+=<>[]{}|:;~'
|
104 | },
|
105 |
|
106 | create (salt = RADIX) {
|
107 | let newTokenizer = new Tokenizer(salt);
|
108 | return newTokenizer;
|
109 | }
|
110 |
|
111 | };
|