내용으로 건너뛰기
사용자 도구
로그인
사이트 도구
도구
문서 보기
이전 판
백링크
최근 바뀜
미디어 관리
사이트맵
로그인
최근 바뀜
미디어 관리
사이트맵
기술자료
작업공간
개인공간
사이트맵
추적:
kb:base64encoding
이 문서는 읽기 전용입니다. 원본을 볼 수는 있지만 바꿀 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하세요.
====== Base64 Encoding ====== MIME과 관련된 곳에서 자주 쓰이는 base64 인코딩/디코딩 모듈이다. 바이너리를 문자열로, 문자열을 바이너리로 변환시켜주는 알고리즘이다. MIME과 관련된 것은 아니지만, 암호화와 관련해서 필요할 때가 있는데, Win32에서는 XP에서만 문자열 인코딩 관련 API가 있기 때문에 이렇게 따로 만들게 되었다. ====== C++ Implementation ====== <file cpp Base64.h> #ifndef __BASE64_H__ #define __BASE64_H__ //////////////////////////////////////////////////////////////////////////////// /// \class Base64 /// \brief 바이너리 값을 base64로 인코딩하거나, 또는 그 반대로 디코딩하는 일과 /// 관련된 함수들을 모아놓은 클래스이다. /// /// 예를 들어 'ABCD'라는 스트림은 총 32비트다. 이는 다음과 같이 매핑된다. /// /// <pre> /// ABCD /// /// A (65) B (66) C (67) D (68) (None) (None) /// 01000001 01000010 01000011 01000100 /// /// 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=) /// 010000 010100 001001 000011 010001 000000 000000 000000 /// /// QUJDRA== /// </pre> /// /// 유닛 테스트를 위한 케이스를 들어보자면 다음과 같다. /// - 빈 문자열 : -> -> /// - 1 글자 : A -> QQ== -> A /// - 2 글자 : AB -> QUJD -> AB /// - 3 글자 : ABC -> QUJD -> ABC /// - 4 글자 : ABCD -> QUJDRA== -> ABCD //////////////////////////////////////////////////////////////////////////////// class Base64 { private: unsigned char* m_Text; ///< NULL로 끝나는 문자열 버퍼 unsigned char* m_Binary; ///< 바이너리 버퍼 size_t m_binarySize; ///< 바이너리 버퍼의 길이 public: /// \brief 생성자 Base64(); /// \brief 소멸자 ~Base64(); public: /// \brief 바이너리를 base64 문자열로 인코딩한다. const unsigned char* Encode(const unsigned char* binary, size_t binarySize); /// \brief base64 문자열을 바이너리로 디코딩한다. const unsigned char* Decode(const unsigned char* text, size_t& binarySize); private: /// \brief 3개의 8비트 바이너리를 4개의 6비트 문자열로 인코딩한다. void EncodeBlock(unsigned char in[3], unsigned char out[4], int len); /// \brief 4개의 6비트 문자열을 3개의 8비트 바이너리로 디코딩한다. void DecodeBlock(unsigned char in[4], unsigned char out[3]); /// \brief 복사 생성자는 금지 Base64(const Base64&) {} /// \brief 대입 연산자는 금지 Base64& operator = (const Base64&) { return *this; } }; #endif //__BASE64_H__ </file> <file cpp Base64.cpp> #include "Base64.h" #include <stdio.h> #include <stdlib.h> #include <vector> namespace { // 인코딩을 위한 테이블 (RFC1113) const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // 디코딩을 위한 테이블 const char DecodeTable[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; } /// \brief 생성자 Base64::Base64() : m_Binary(NULL), m_Text(NULL) { } /// \brief 소멸자 Base64::~Base64() { if (m_Binary != NULL) delete [] m_Binary; if (m_Text != NULL) delete [] m_Text; } /// \brief 바이너리를 base64 문자열로 인코딩한다. const unsigned char* Base64::Encode(const unsigned char* binary, size_t binarySize) { unsigned char in[3]; unsigned char out[4]; int len; int blocksout = 0; size_t current = 0; std::vector<unsigned char> intermediate; // 인코딩한다. while (current < binarySize) { len = 0; for (int i = 0; i < 3; i++) { in[i] = binary[current]; if (current < binarySize) { current++; len++; } else { in[i] = 0; } } if (len) { EncodeBlock(in, out, len); for (int i = 0; i < 4; i++) intermediate.push_back(out[i]); } } // 벡터에 있는 값을 텍스트 버퍼에 복사하기 이전에, // 기존의 텍스트 버퍼를 삭제하고, 벡터의 크기만큼 메모리를 재할당 if (m_Text != NULL) delete [] m_Text; m_Text = new unsigned char[intermediate.size()+1]; memset(m_Text, 0, sizeof(unsigned char) * (intermediate.size()+1)); // 벡터에 있는 내용을 텍스트 버퍼에 복사 for (size_t r=0; r<intermediate.size(); r++) m_Text[r] = intermediate[r]; return m_Text; } /// \brief base64 문자열을 바이너리로 디코딩한다. const unsigned char* Base64::Decode(const unsigned char* text, size_t& binarySize) { unsigned char in[4]; unsigned char out[3]; unsigned char v; int i; int len; size_t current = 0; std::vector<unsigned char> intermediate; size_t TextSize = strlen((const char*)text); while (current < TextSize) { for (i = 0, len = 0; i < 4 && current < TextSize; i++) { v = 0; while (current < TextSize && v == 0) { v = text[current]; if (current < TextSize) current++; v = (unsigned char) ((v < 43 || v > 122) ? 0 : DecodeTable[v - 43]); if (v) { v = (unsigned char) ((v == '$') ? 0 : v - 61); } } if (current < TextSize) { len++; if (v) { in[i] = (unsigned char) (v - 1); } } else { in[i] = 0; } } if (len) { DecodeBlock(in, out); for (i = 0; i < len - 1; i++) intermediate.push_back(out[i]); } } // 중간 버퍼에 있는 값을 바이너리 버퍼로 옮겨야한다. // 기존의 바이너리 버퍼를 삭제하고, 벡터의 크기만큼 메모리를 재할당 // 서비스로 +1 크기만큼의 버퍼를 만들어 끝에다 0을 집어넣어준다. if (m_Binary != NULL) delete [] m_Binary; m_Binary = new unsigned char[intermediate.size()+1]; memset(m_Binary, 0, sizeof(unsigned char) * (intermediate.size()+1)); // 벡터에 있는 내용을 바이너리 버퍼에 복사 for (size_t r=0; r<intermediate.size(); r++) m_Binary[r] = intermediate[r]; // 사이즈 변수를 세팅 binarySize = intermediate.size(); return m_Binary; } /// \brief 3개의 8비트 바이너리를 4개의 6비트 문자열로 인코딩한다. void Base64::EncodeBlock(unsigned char in[3], unsigned char out[4], int len) { out[0] = EncodeTable[in[0] >> 2]; out[1] = EncodeTable[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)]; out[2] = (unsigned char) (len > 1 ? EncodeTable[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)] : '='); out[3] = (unsigned char) (len > 2 ? EncodeTable[in[2] & 0x3f] : '='); } /// \brief 4개의 6비트 문자열을 3개의 8비트 바이너리로 디코딩한다. void Base64::DecodeBlock(unsigned char in[4], unsigned char out[3]) { out[0] = (unsigned char) (in[0] << 2 | in[1] >> 4); out[1] = (unsigned char) (in[1] << 4 | in[2] >> 2); out[2] = (unsigned char) (((in[2] << 6) & 0xc0) | in[3]); } </file> ====== 링크 ====== * [[http://en.wikipedia.org/wiki/Base64 | Base64 on Wikipedia]] ---- * see also [[Cryptography]]
kb/base64encoding.txt
· 마지막으로 수정됨: 2014/11/10 19:50 (바깥 편집)
문서 도구
문서 보기
이전 판
백링크
맨 위로