본문 바로가기
dev/javascript

[javascript] 자바스크립트 base64 사용 방법 (btoa, atob)

by 최연탄 2022. 6. 30.
728x90
반응형

참고: https://attacomsian.com/blog/javascript-base64-encode-decode

Base64는 바이너리 데이터를 64진법 표현으로 변환하여 정해진 ASCII 문자 집합으로 표현하는 바이너리-텍스트 인코딩 체계입니다. 이는 일반적으로 바이너리 데이터를 전송할 수 없는 미디어에서 전송 작업을 할 수 있도록 바이너리 데이터를 문자열로 인코딩하는데 사용됩니다. Base64는 전송 중에 이진 데이터가 손실되지 않도록 합니다.

Base64는 암호화나 압축하는 체계가 아닙니다. 그저 네트워크를 통해 난독화된 문자열을 전송할 수 있도록 바이너리 데이터를 ASCII 문자 집합으로 변환합니다. 예를 들면 텍스트 데이터를 받는 이메일 서버에 이미지나 파일을 보내는 경우가 있습니다. 이 때 파일을 텍스트 형식으로 인코딩해야 합니다.

이 글에서는 JavaScript에서 Base64 문자열을 인코딩 및 디코딩 하는 방법을 설명합니다. 원시 바이너리 데이터를 Base64 문자열로 인코딩 및 디코딩하기 위해 JavaScript에서는 두 가지 내장 함수를 지원합니다.

btoa() - Base64 Encoding

btoa() 메소드(binary to ascii의 약자)는 바이너리 데이터를 Base64로 인코딩된 ASCII 문자열로 만드는데 사용합니다. 이는 바이너리 문자열을 매개변수로 받아 Base64로 인코딩된 ASCII 문자열을 반환합니다.

다음의 예제는 btoa() 메소드를 사용해 Base64로 인코딩된 문자열을 만드는 JavaScript 코드입니다.

const str = "JavaScript is fun!!";

// encode the string
const encodedStr = btoa(str);

// print encoded string
console.log(encodedStr);

// output: SmF2YVNjcmlwdCBpcyBmdW4hIQ==

기본적으로 btoa() 메소드는 바이트로 이루어진 바이너리 데이터를 매개변수로 전달해도 잘 작동합니다. 만약 입력 값에 유니코드 문자같이 8비트 이상의 크기를 가지는 문자가 포함되면 btoa() 메소드는 exception을 발생합니다. 다음은 이런 상황의 예제 입니다.

const str = "JavaScript is fun 🎉";

// encode the string
const encodedStr = btoa(str);

// print encoded string
console.log(encodedStr);

위의 예제 코드를 실행하면 그림과 같은 에러가 발생합니다.

유니코드 문자를 인코딩하려면 먼저 입력 문자열을 8비트 바이트 배열(UTF-8 처럼)로 변환한다음 btoa() 메소드를 사용하여 다음 예제와 같이 Base64로 인코딩해야 합니다.

function encodeUnicode(str) {
  return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
      function toSolidBytes(match, p1) {
          return String.fromCharCode('0x' + p1);
  }));
}

encodeUnicode('JavaScript is fun 🎉'); // SmF2YVNjcmlwdCBpcyBmdW4g8J+OiQ==
encodeUnicode('🔥💡'); // 8J+UpfCfkqE=

atob() - Base64 Decoding

atob() 메소드(ascii to binary의 약자)는 Base64로 인코딩된 문자열을 일반 문자열로 디코딩합니다. 다음은 atob() 메소드로 Base64 문자열을 디코딩하는 예제입니다.

const encodedStr = "SmF2YVNjcmlwdCBpcyBmdW4hIQ==";

// decode the string
const str = atob(encodedStr);

// print decoded string
console.log(str);

// output: JavaScript is fun!!

atob() 메소드는 Base64 문자열이 순수하게 8비트로 이루어진 문자열일때만 완벽하게 작동합니다. 인코딩된 입력 값이 16비트 유니코드 문자가 포함되어있다면 다음 예제 처럼 제대로 디코딩되지 않습니다.

// Encode String: 'JavaScript is fun 🎉'
const encodedStr = "SmF2YVNjcmlwdCBpcyBmdW4g8J+OiQ==";

// decode the string
const str = atob(encodedStr);

// print decoded string
console.log(str);

// output: JavaScript is fun 🎉

위 예제에서 볼 수 있듯이 유니코드 문자열은 제대로 디코딩되지 않습니다. 유니코드 DOM 문자열을 처리하기 위해서는 Base64 인코딩 바이트를 퍼센트 인코딩으로 변환한 다음 decodeURIComponent() 메소드를 사용하여 디코딩해야 합니다.

function decodeUnicode(str) {
  // Going backwards: from bytestream, to percent-encoding, to original string.
  return decodeURIComponent(atob(str).split('').map(function (c) {
    return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  }).join(''));
}

decodeUnicode('SmF2YVNjcmlwdCBpcyBmdW4g8J+OiQ=='); // JavaScript is fun 🎉
decodeUnicode('8J+UpfCfkqE='); // 🔥💡

정리

Base64는 바이너리 데이터를 ASCII 문자 스트림으로 안전하게 전송하기위해 널리 쓰이는 인코딩 체계입니다. 물론 Base64 인코딩을 안하고 네트워크를 통해 그냥 바이너리 데이터를 보낼 수도 있습니다. 하지만 모든 응용프로그램과 네트워크 통신 장치가 원시 바이너리 데이터를 처리할 수 있는 것은 아니기 때문에 때로는 위험할 수도 있습니다. 반면에 ASCII 문자 집합은 대부분의 응용프로그램에서 다루기가 간편합니다.

관련 글

자바스크립트 이미지를 base64로 변환

반응형

댓글