TIL/개인 TIL

TIL :: uuid 인코딩 / 디코딩

두캔두잇 2023. 11. 17. 01:13

사이드프로젝트를 하다가 조회로직을 작성하려고 했다. 근데 생각해보니 처음 id를 uuid 타입으로 사용을 해서 조회를 할 때, 문자열로 들어오는 값들을 다 넣어야 하나?? 라고 생각이 들어 실행을 해봤더니 다 넣어야했다..그래서 url의 길이가 너무 길어져 줄이고싶어 방법을 알아보다가 uuid를 인코딩에서 보내주고 다시 디코딩한 값을 읽게 할 수 있다는걸 알게되어 적용해봤다.

 

우선 위와 같이, 임포트를 해주는데 처음에 base62라이브러리를 사용하려했지만, 버전 관리등 문제가 생겨 다른 라이브러리인 base-X 를 사용했다. 그래서 선언해주고 아래에 base62 인코딩 방식에서 사용되는 62개의 문자를 정의하고, 정의한 문자들을 baseX로 사용하기위하여 정의하였다.

 

다음으로는, 인코딩/디코딩할 함수들을 만들어 줄건데 하나씩 보면 다음과 같다.

 

base62 형식으로 인코딩

1. toBase62 함수

이 메서드는 uuid 형식의 문자열을 받을 때 base62 형식으로 인코딩을 하려고 만들었다. 첫 번째로는 입력받은 uuid가 유효한 형식이 아닐 경우에 오류를 반환하도록 만들었고, 다음은 uuid를 byte로 만들었다. 그리고나서 반환된 byte들을 Buffer를 사용해 만들고 base62.encode를 통해 인코딩을 하도록 만들었다.

# 사실 처음엔 Buffer를 사용하지 않고 bytes 와 encoded를 콘솔을 찍어 확인을 해봤는데 encoded쪽이 아무 값도 나오지 않아서 이유를 찾다가 base62 라이브러리를 사용하다가 Buffer 객체를 인자로 받아야하는 경우도 있고 uuidParse(uuid) 쪽이 Uint8Array를 반환한다고해서 이 부분쪽이 호환문제가 발생한것 같아서 저렇게 추가하여 호출하였다. 그 결과는, 둘 다 로그에 잘 찍혔다.

console.log 성공

 

2. fromBase62 함수

 

이 메서드는 위에와 반대로 base62 형식의 문자열을 받을 때 uuid형식으로 디코딩 하는 함수이다.

 

위와 같이 먼저 입력된 encoded라는 매개변수의 문자열이 유효한지 확인을 하고 그렇지 않으면 에러를 반환하도록 했다.

그리고 base62.decode를 통해 매개변수 encoded의 값들을 byte 로 디코딩하였다. 그리고 한 가지 다른 점은, uuid는 항상 16바이트이기 때문에 길이를 비교해서 다를 경우에는 에러를 반환하도록 하였다. 마지막으로 디코딩된 byte 배열들을 uuid 형식으로 반환했다.

 

추가적으로 아래와 같이 입력된 값들이 유효한지 검증하는 로직들을 추가해 주었다.

 // 입력된 uuid가 유효한지 검증
  static isValidUuid(uuid: string): boolean {
    // 해당 문자열 인코딩 문자열 검사
    return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(uuid);
  }

  // 입력된 base62가 유효한지 검증
  static isValidBase62(str: string): boolean {
    // 해당 문자열 인코딩 문자열 검사
    return /^[0-9a-zA-Z]+$/.test(str);
  }

 


Controller

user.controller.ts

인코딩/디코딩을 하는 목적은 포스트맨으로 조회를 할 때, 받는 url의 길이가 길어져서 나는, 그 url의 길이를 인코딩된 값,디코딩된 값 

둘 다로 조회를 하기 위해 findByUser(uuid 형식일 경우) 와 gerFindByUser(base62 형식일 경우) 라는 함수를 만들었다.

 

Service

user.service.ts

findByUser 함수를 보면 먼저 prisma.findUnique라는 메서드를 사용해서 해당 ID를 찾고, 조회된 유저의 정보는 IFindUser 라는 인터페이스를 만들어 타입캐스팅을 하였다. 그리고 사용자를 찾지못하면 오류를 발생시키게하고 찾은 유저의 ID를 base62로 인코딩하고 Id 라는 필드에 저장하도록하였다.

 

두 번째, getFindByUser 함수를 보면 입력받은 encodedId를 base62로 디코딩하여 uuid에 저장시키고 그것이 실패했을 때는 catch문을 통하여 에러를 반환하도록 하였다. 그리고 디코딩된 uuid를 사용하여 prisma.findUnique 메서드를 통해 DB에서 조회를 하고 id 필드에는 인코딩된 id를 그대로 저장하도록 하였다.

 

 

## 결과 ##