Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
4kimov committed Jul 17, 2023
1 parent a448a9b commit 3311be3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 61 deletions.
119 changes: 61 additions & 58 deletions src/sqids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export default class Sqids {
const minLength = options?.minLength ?? defaultOptions.minLength
const blocklist = options?.blocklist ?? new Set<string>(defaultBlocklist)

if (alphabet.length < 5) {
const minAlphabetLength = 5
if (alphabet.length < minAlphabetLength) {
throw new Error('Alphabet length must be at least 5')
}

Expand Down Expand Up @@ -76,11 +77,67 @@ export default class Sqids {
return this.encodeNumbers(numbers, false)
}

decode(id: string): number[] {
const ret: number[] = []

if (id === '') {
return ret
}

const alphabetChars = this.alphabet.split('')
for (const c of id.split('')) {
if (!alphabetChars.includes(c)) {
return ret
}
}

const prefix = id.charAt(0)
const offset = this.alphabet.indexOf(prefix)
let alphabet = this.alphabet.slice(offset) + this.alphabet.slice(0, offset)
const partition = alphabet.charAt(1)
alphabet = alphabet.slice(2)
id = id.slice(1)

const partitionIndex = id.indexOf(partition)
if (partitionIndex > 0 && partitionIndex < id.length - 1) {
id = id.slice(partitionIndex + 1)
alphabet = this.shuffle(alphabet)
}

while (id.length > 0) {
const separator = alphabet.slice(-1)

const chunks = id.split(separator)
if (chunks.length > 0) {
const alphabetWithoutSeparator = alphabet.slice(0, -1)
ret.push(this.toNumber(chunks[0]!, alphabetWithoutSeparator))

if (chunks.length > 1) {
alphabet = this.shuffle(alphabet)
}
}

id = chunks.slice(1).join(separator)
}

return ret
}

minValue() {
return 0
}

maxValue() {
return Number.MAX_SAFE_INTEGER
}

private encodeNumbers(numbers: number[], partitioned = false): string {
const offset =
numbers.reduce((a, v, i) => {
return this.alphabet[v % this.alphabet.length]!.codePointAt(0)! + i + a
}, numbers.length) % this.alphabet.length
numbers.reduce(
(a, v, i) =>
this.alphabet[v % this.alphabet.length]!.codePointAt(0)! + i + a,
numbers.length,
) % this.alphabet.length

let alphabet = this.alphabet.slice(offset) + this.alphabet.slice(0, offset)

Expand Down Expand Up @@ -144,60 +201,6 @@ export default class Sqids {
return id
}

decode(id: string): number[] {
const ret: number[] = []

if (id === '') {
return ret
}

const alphabetChars = this.alphabet.split('')
for (const c of id.split('')) {
if (!alphabetChars.includes(c)) {
return ret
}
}

const prefix = id.charAt(0)
const offset = this.alphabet.indexOf(prefix)
let alphabet = this.alphabet.slice(offset) + this.alphabet.slice(0, offset)
const partition = alphabet.charAt(1)
alphabet = alphabet.slice(2)
id = id.slice(1)

const partitionIndex = id.indexOf(partition)
if (partitionIndex > 0 && partitionIndex < id.length - 1) {
id = id.slice(partitionIndex + 1)
alphabet = this.shuffle(alphabet)
}

while (id.length) {
const separator = alphabet.slice(-1)

const chunks = id.split(separator)
if (chunks.length) {
const alphabetWithoutSeparator = alphabet.slice(0, -1)
ret.push(this.toNumber(chunks[0]!, alphabetWithoutSeparator))

if (chunks.length > 1) {
alphabet = this.shuffle(alphabet)
}
}

id = chunks.slice(1).join(separator)
}

return ret
}

minValue() {
return 0
}

maxValue() {
return Number.MAX_SAFE_INTEGER
}

private shuffle(alphabet: string): string {
const chars = alphabet.split('')

Expand Down
6 changes: 3 additions & 3 deletions src/tests/minlength.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ test('incremental numbers', () => {
})

test('min lengths', () => {
const sqids = new Sqids()
const s = new Sqids()

for (const minLength of [0, 1, 5, 10, defaultOptions.alphabet.length]) {
for (const numbers of [
[sqids.minValue()],
[s.minValue()],
[0, 0, 0, 0, 0],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[100, 200, 300],
[1_000, 2_000, 3_000],
[1_000_000],
[sqids.maxValue()],
[s.maxValue()],
]) {
const sqids = new Sqids({
minLength,
Expand Down

0 comments on commit 3311be3

Please sign in to comment.