Files
start-sdk/lib/util/getDefaultString.ts
2023-05-04 15:59:25 -06:00

113 lines
2.8 KiB
TypeScript

import { DefaultString } from "../config/configTypes"
export function getDefaultString(defaultSpec: DefaultString): string {
if (typeof defaultSpec === "string") {
return defaultSpec
} else {
let s = ""
for (let i = 0; i < defaultSpec.len; i++) {
s = s + getRandomCharInSet(defaultSpec.charset)
}
return s
}
}
// a,g,h,A-Z,,,,-
export function getRandomCharInSet(charset: string): string {
const set = stringToCharSet(charset)
let charIdx = Math.floor(Math.random() * 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
}