mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
merge 036, everything broken
This commit is contained in:
98
sdk/lib/util/getRandomCharInSet.ts
Normal file
98
sdk/lib/util/getRandomCharInSet.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
// a,g,h,A-Z,,,,-
|
||||
|
||||
import * as crypto from "crypto"
|
||||
export function getRandomCharInSet(charset: string): string {
|
||||
const set = stringToCharSet(charset)
|
||||
let charIdx = crypto.randomInt(0, set.len)
|
||||
for (let range of set.ranges) {
|
||||
if (range.len > charIdx) {
|
||||
return String.fromCharCode(range.start.charCodeAt(0) + charIdx)
|
||||
}
|
||||
charIdx -= range.len
|
||||
}
|
||||
throw new Error("unreachable")
|
||||
}
|
||||
function stringToCharSet(charset: string): CharSet {
|
||||
let set: CharSet = { ranges: [], len: 0 }
|
||||
let start: string | null = null
|
||||
let end: string | null = null
|
||||
let in_range = false
|
||||
for (let char of charset) {
|
||||
switch (char) {
|
||||
case ",":
|
||||
if (start !== null && end !== null) {
|
||||
if (start!.charCodeAt(0) > end!.charCodeAt(0)) {
|
||||
throw new Error("start > end of charset")
|
||||
}
|
||||
const len = end.charCodeAt(0) - start.charCodeAt(0) + 1
|
||||
set.ranges.push({
|
||||
start,
|
||||
end,
|
||||
len,
|
||||
})
|
||||
set.len += len
|
||||
start = null
|
||||
end = null
|
||||
in_range = false
|
||||
} else if (start !== null && !in_range) {
|
||||
set.len += 1
|
||||
set.ranges.push({ start, end: start, len: 1 })
|
||||
start = null
|
||||
} else if (start !== null && in_range) {
|
||||
end = ","
|
||||
} else if (start === null && end === null && !in_range) {
|
||||
start = ","
|
||||
} else {
|
||||
throw new Error('unexpected ","')
|
||||
}
|
||||
break
|
||||
case "-":
|
||||
if (start === null) {
|
||||
start = "-"
|
||||
} else if (!in_range) {
|
||||
in_range = true
|
||||
} else if (in_range && end === null) {
|
||||
end = "-"
|
||||
} else {
|
||||
throw new Error('unexpected "-"')
|
||||
}
|
||||
break
|
||||
default:
|
||||
if (start === null) {
|
||||
start = char
|
||||
} else if (in_range && end === null) {
|
||||
end = char
|
||||
} else {
|
||||
throw new Error(`unexpected "${char}"`)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start !== null && end !== null) {
|
||||
if (start!.charCodeAt(0) > end!.charCodeAt(0)) {
|
||||
throw new Error("start > end of charset")
|
||||
}
|
||||
const len = end.charCodeAt(0) - start.charCodeAt(0) + 1
|
||||
set.ranges.push({
|
||||
start,
|
||||
end,
|
||||
len,
|
||||
})
|
||||
set.len += len
|
||||
} else if (start !== null) {
|
||||
set.len += 1
|
||||
set.ranges.push({
|
||||
start,
|
||||
end: start,
|
||||
len: 1,
|
||||
})
|
||||
}
|
||||
return set
|
||||
}
|
||||
type CharSet = {
|
||||
ranges: {
|
||||
start: string
|
||||
end: string
|
||||
len: number
|
||||
}[]
|
||||
len: number
|
||||
}
|
||||
Reference in New Issue
Block a user