Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL 단축 #41

Open
Phryxia opened this issue Sep 21, 2022 · 3 comments
Open

URL 단축 #41

Phryxia opened this issue Sep 21, 2022 · 3 comments
Assignees
Labels
improve Improve features that already exist

Comments

@Phryxia
Copy link
Owner

Phryxia commented Sep 21, 2022

현재는 게시글 제목을 인코딩 한 것으로 URL을 사용하고 있다. 그런데 이 방식의 문제는 조금만 제목이 길어져도 URL이 극도로 지저분해진다는 것이다.

예시: https://nuko-library-v3.vercel.app/posts/dev/typescript/%25ED%2583%2580%25EC%259E%2585%25EC%25B6%2594%25EB%25A1%25A0/%25ED%2583%2580%25EC%259E%2585%25EC%258A%25A4%25ED%2581%25AC%25EB%25A6%25BD%25ED%258A%25B8%2520%25ED%2583%2580%25EC%259E%2585%2520%25EC%25B6%2594%25EB%25A1%25A0%2520%25EC%259D%25B4%25ED%2595%25B4%25ED%2595%2598%25EA%25B8%25B0%2520(1)

URL 단축은 다음과 같은 성질을 가져야 한다.

  • 배포를 여러 번 하더라도, 동일한 경로의 글은 동일한 단축 URL을 갖는다.

기존 호환성을 보장하기 위해, 단축 URL이 아닌 접근에 대해서도 단축 URL로 리다이렉션해야 한다.

@Phryxia Phryxia added the improve Improve features that already exist label Sep 21, 2022
@Phryxia Phryxia self-assigned this Sep 21, 2022
@Phryxia
Copy link
Owner Author

Phryxia commented Sep 21, 2022

// compact.ts
export function createCompactor() {
  const encodeMap: Record<string, number> = {}
  const decodeList: string[] = []

  const special = "!%'()-._~"
  for (let i = 0; i < special.length; ++i) {
    const c = special[i]
    encodeMap[c] = i
    decodeList.push(c)
  }

  let bias = decodeList.length
  for (let i = 0; i < 10; ++i) {
    const c = i.toString()
    encodeMap[c] = bias + i
    decodeList.push(c)
  }

  bias = decodeList.length
  for (let i = 0; i < 26; ++i) {
    const c = String.fromCharCode('a'.charCodeAt(0) + i).toString()
    encodeMap[c] = bias + i
    decodeList.push(c)
  }

  bias = decodeList.length
  for (let i = 0; i < 26; ++i) {
    const c = String.fromCharCode('A'.charCodeAt(0) + i).toString()
    encodeMap[c] = bias + i
    decodeList.push(c)
  }

  return { encodeMap, decodeList }
}

@Phryxia
Copy link
Owner Author

Phryxia commented Sep 21, 2022

// encode.ts
import { createCompactor } from './compact'

const { decodeList, encodeMap } = createCompactor()
const DECODE_SIZE = decodeList.length

function charToNumber(s: string): number {
  return encodeMap[s]
}

function numberToChar(x: number): string {
  return decodeList[x]
}

function subtract(a: number, b: number): number {
  return (a + DECODE_SIZE - b) % DECODE_SIZE
}

function multiply(a: number, b: number): number {
  return (a * b) % DECODE_SIZE
}

export function encode(s: string, n: number): string {
  s = encodeURIComponent(s)

  const temp: number[] = []
  for (let i = s.length - 1; i >= 0; --i) {
    temp[i] = subtract(charToNumber(s[i]), temp[i + 1] ?? 0)
  }
  for (let i = 0; i < n; ++i) {
    temp[i] = multiply(charToNumber(s[i]), temp[i])
  }

  return temp.slice(0, n).map(numberToChar).join('')
}

@Phryxia
Copy link
Owner Author

Phryxia commented Sep 26, 2022

단축은 되지만 URL이 의미가 너무 없어서, 발상을 바꿔서 공유할 때에만 단축 URL을 쓰게 하고, 들어올 때 단축 URL을 지원하는게 더 좋을 거 같다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improve Improve features that already exist
Projects
None yet
Development

No branches or pull requests

1 participant