-
Notifications
You must be signed in to change notification settings - Fork 0
/
ulid.js
37 lines (34 loc) · 907 Bytes
/
ulid.js
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
const lookup = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
const base32 = array => {
const size = array.BYTES_PER_ELEMENT * 8
const b32_length = Math.ceil(array.length * size / 5)
const buffer = new Array(b32_length)
let pointer = array.length
let acc = array[--pointer]
let bits = size
for (let i=b32_length-1; i>=0; --i) {
while (bits < 5) {
if (pointer > 0)
acc += (array[--pointer] * 2 ** bits)
bits += size
}
buffer[i] = lookup[acc % 32]
acc = Math.floor(acc / 32)
bits -= 5
}
return buffer.join('')
}
const bytes = length => integer => {
const array = new Uint8Array(length)
for (let i=length-1; i>=0; --i) {
array[i] = Math.floor(integer % 256)
integer = integer / 256
}
return array
}
export default (time = Date.now()) => {
const array = new Uint8Array(16)
array.set(bytes(6)(time))
array.set(crypto.getRandomValues(new Uint8Array(10)), 6)
return base32(array)
}