forked from utily/cryptly
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIdentifier.ts
More file actions
126 lines (124 loc) · 2.63 KB
/
Identifier.ts
File metadata and controls
126 lines (124 loc) · 2.63 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import * as Base64 from "./Base64"
import { crypto } from "./crypto"
export type Identifier = string
export namespace Identifier {
export function is(value: Identifier | any, length?: Length): value is Identifier {
return (
typeof value == "string" &&
(length == undefined || value.length == length) &&
Array.from(value).every(
c => (c >= "0" && c <= "9") || (c >= "A" && c <= "Z") || (c >= "a" && c <= "z") || c == "-" || c == "_"
)
)
}
export function fromUint24(value: number): Identifier {
return fromHexadecimal(value.toString(16).padStart(6, "0"))
}
export function toUint24(identifier: Identifier): number {
return Number.parseInt(toHexadecimal(identifier, 6), 16)
}
export function fromUint48(value: number): Identifier {
return fromHexadecimal(value.toString(16).padStart(12, "0"))
}
export function toUint48(identifier: Identifier): number {
return Number.parseInt(toHexadecimal(identifier, 12), 16)
}
export function fromBinary(identifier: Uint8Array): Identifier {
return Base64.encode(identifier, "url")
}
export function toBinary(identifier: Identifier): Uint8Array {
return Base64.decode(identifier, "url")
}
export function generate(length: Length): Identifier {
return fromBinary(crypto.getRandomValues(new Uint8Array((length / 4) * 3)))
}
export function fromHexadecimal(identifier: string): Identifier {
if (identifier.length % 2 == 1)
identifier += "0"
const result = new Uint8Array(identifier.length / 2)
for (let index = 0; index < result.length; index++)
result[index] = Number.parseInt(identifier[index * 2], 16) * 16 + Number.parseInt(identifier[index * 2 + 1], 16)
return fromBinary(result)
}
export function toHexadecimal(identifier: Identifier, length?: number): string {
const data = Base64.decode(identifier, "url")
let result: string[] = []
for (const d of data)
result.push(Math.floor(d / 16).toString(16), (d % 16).toString(16))
if (length)
result = result.slice(0, length)
return result.join("")
}
export const length = [
4,
8,
12,
16,
20,
24,
28,
32,
36,
40,
44,
48,
52,
56,
60,
64,
68,
72,
76,
80,
84,
88,
92,
96,
100,
104,
108,
112,
116,
120,
124,
128,
] as Length[]
export type Length =
| 4
| 8
| 12
| 16
| 20
| 24
| 28
| 32
| 36
| 40
| 44
| 48
| 52
| 56
| 60
| 64
| 68
| 72
| 76
| 80
| 84
| 88
| 92
| 96
| 100
| 104
| 108
| 112
| 116
| 120
| 124
| 128
export namespace Length {
export function is(value: Length | any): value is Length {
return typeof value == "number" && value >= 4 && value <= 128 && (value & 252) == value
}
}
}