1. Base64 인코딩의 유래
Base64 인코딩이 있는 이유는 무엇인가요? 예를 들어 일부 네트워크 전송 채널은 모든 바이트를 지원하지 않기 때문에 기존 메일은 보이는 문자의 전송만 지원하고 ASCII 코드와 같은 제어 문자는 메일을 통해 전송할 수 없습니다. 이러한 방식으로 사용이 크게 제한됩니다. 예를 들어 이미지 바이너리 스트림의 각 바이트는 모두 표시되는 문자일 수 없으므로 전송할 수 없습니다. 가장 좋은 방법은 기존 프로토콜을 변경하지 않고 바이너리 파일 전송을 지원하는 확장 솔루션을 만드는 것입니다. 인쇄할 수 없는 문자도 인쇄할 수 있는 문자로 표현할 수 있으면 문제가 해결됩니다. Base64 인코딩이 등장했습니다. Base64는 이진 데이터를 표현하기 위해 인쇄 가능한 64개의 문자를 기반으로 하는 표현 방법입니다.
2. Base64 인코딩 원리
Base64 인덱스 테이블을 보면 문자는 "A-Z, a-z, 0-9, +, /" 64개의 인쇄 가능한 문자입니다. 숫자 값은 문자의 인덱스를 나타냅니다. 이는 표준 Base64 프로토콜에 의해 지정되며 변경할 수 없습니다. 64개의 문자를 모두 6비트로 표현할 수 있으며, 1바이트는 8비트로 나머지 2비트는 낭비되기 때문에 일부 공간을 희생해야 합니다. 여기서 이해해야 할 것은 Base64 문자는 8비트인데 유효부분은 오른쪽의 6비트뿐이고 왼쪽 2비트는 항상 0이라는 점이다.
그럼 8비트의 전통 문자를 표현하기 위해 6개의 유효 비트를 어떻게 사용합니까? 8과 6의 최소 공배수는 24입니다. 즉, 기존 바이트 3개를 Base64 문자 4개로 표현할 수 있어 유효 자릿수가 동일하므로 이를 보완할 바이트가 1/3 더 있습니다. Base64에는 유효한 비트가 6개 부족합니다. 두 개의 Base64 문자도 전통적인 문자를 나타낼 수 있다고 말할 수 있지만 최소 공배수를 사용하는 솔루션은 실제로 가장 낭비입니다. 아래 그림을 보면 이해가 더 쉽습니다. Man은 3개의 문자로 총 24개의 유효한 비트가 있으므로 24개의 유효한 비트를 얻으려면 4개의 Base64 문자를 사용해야 합니다. 빨간색 상자는 해당 Base64를 나타냅니다. 6개의 유효 비트를 해당 인덱스 값으로 변환한 후 "Man"에 해당하는 Base64 문자가 "TWFU"임을 알 수 있습니다. 그러고보니 원리가 있는데, Base64로 변환하는 가장 작은 단위는 3바이트인데, 문자열의 경우 매번 3바이트씩 변환을 하게 됩니다. Base64의 4바이트에 해당합니다. 이것을 알아내고 나면 실제로는 거의 같은 것입니다.
그런데 변환이 끝났을 때 3바이트가 부족하다고 판단되면 어떻게 해야 할까요? 드디어 소원이 이루어졌습니다. 두 개의 Base64를 사용하여 한 문자를 나타내거나 세 개의 Base64를 사용하여 두 문자를 나타낼 수 있습니다. 아래 그림에서 볼 수 있듯이 A에 해당하는 두 번째 Base64에는 다음 네 개가 0으로 채워집니다. 그게 다야. 따라서 A에 해당하는 Base64 문자는 QQ입니다. 위에서 언급했듯이 Base64 문자의 최소 단위는 4개의 문자로 구성된 그룹이므로 원칙적으로 이는 2개의 문자 뒤에 "="가 2개만 붙는 것입니다. 실제로 "="를 사용하지 않으면 디코딩이 지연되지 않습니다. "="를 사용하는 이유는 다중 섹션으로 인코딩된 Base64 문자열을 조합할 때 혼동을 일으키지 않기 때문일 수 있습니다. Base64 문자열의 끝에는 한두 개의 "="만 나타날 수 있으며 중간에는 "="가 나타날 수 없음을 알 수 있습니다. 아래 그림의 문자 "BC"의 인코딩 과정도 동일합니다.
3. Node.js 일반 문자열 인코딩 및 디코딩:
var b = new Buffer('JavaScript'); var s = b.toString('base64'); // SmF2YVNjcmlwdA== var b = new Buffer('SmF2YVNjcmlwdA==', 'base64') var s = b.toString(); // JavaScript
인코딩, 디코딩 및 변환 hex
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64') var s = b.toString('hex'); // 4a617661536372697074 var b = new Buffer('4a617661536372697074', 'hex') var s = b.toString('utf8'); // JavaScript
4. node.js 그림 인코딩 및 디코딩
var fs = require('fs'); // function to encode file data to base64 encoded string function base64_encode(file) { // read binary data var bitmap = fs.readFileSync(file); // convert binary data to base64 encoded string return new Buffer(bitmap).toString('base64'); } // function to create file from base64 encoded string function base64_decode(base64str, file) { // create buffer object from base64 encoded string, it is important to tell the constructor that the string is base64 encoded var bitmap = new Buffer(base64str, 'base64'); // write buffer to file fs.writeFileSync(file, bitmap); console.log('******** File created from base64 encoded string ********'); } // convert image to base64 encoded string var base64str = base64_encode('kitten.jpg'); console.log(base64str); // convert base64 string back to image base64_decode(base64str, 'copy.jpg');