元サイト
http://yano.hatenadiary.jp/entry/20100908/1283945820
消えたら困るのでメモ
base64.hpp
#ifndef BASE64_HPP_20100908_ #define BASE64_HPP_20100908_ #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <string> #include <vector> namespace algorithm { bool encode_base64(const std::vector<unsigned char>& src, std::string& dst); bool decode_base64(const std::string& src, std::vector<unsigned char>& dst); } #endif
base64.cpp
#include "base64.hpp" // base64 エンコード bool algorithm::encode_base64(const std::vector<unsigned char>& src, std::string& dst) { const std::string table("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); std::string cdst; for (std::size_t i = 0; i < src.size(); ++i) { switch (i % 3) { case 0: cdst.push_back(table[(src[i] & 0xFC) >> 2]); if (i + 1 == src.size()) { cdst.push_back(table[(src[i] & 0x03) << 4]); cdst.push_back('='); cdst.push_back('='); } break; case 1: cdst.push_back(table[((src[i - 1] & 0x03) << 4) | ((src[i + 0] & 0xF0) >> 4)]); if (i + 1 == src.size()) { cdst.push_back(table[(src[i] & 0x0F) << 2]); cdst.push_back('='); } break; case 2: cdst.push_back(table[((src[i - 1] & 0x0F) << 2) | ((src[i + 0] & 0xC0) >> 6)]); cdst.push_back(table[src[i] & 0x3F]); break; } } dst.swap(cdst); return true; } // base64 デコード bool algorithm::decode_base64(const std::string& src, std::vector<unsigned char>& dst) { if (src.size() & 0x00000003) { return false; } else { const std::string table("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); std::vector<unsigned char> cdst; for (std::size_t i = 0; i < src.size(); i += 4) { if (src[i + 0] == '=') { return false; } else if (src[i + 1] == '=') { return false; } else if (src[i + 2] == '=') { const std::string::size_type s1 = table.find(src[i + 0]); const std::string::size_type s2 = table.find(src[i + 1]); if (s1 == std::string::npos || s2 == std::string::npos) { return false; } cdst.push_back(static_cast<unsigned char>(((s1 & 0x3F) << 2) | ((s2 & 0x30) >> 4))); break; } else if (src[i + 3] == '=') { const std::string::size_type s1 = table.find(src[i + 0]); const std::string::size_type s2 = table.find(src[i + 1]); const std::string::size_type s3 = table.find(src[i + 2]); if (s1 == std::string::npos || s2 == std::string::npos || s3 == std::string::npos) { return false; } cdst.push_back(static_cast<unsigned char>(((s1 & 0x3F) << 2) | ((s2 & 0x30) >> 4))); cdst.push_back(static_cast<unsigned char>(((s2 & 0x0F) << 4) | ((s3 & 0x3C) >> 2))); break; } else { const std::string::size_type s1 = table.find(src[i + 0]); const std::string::size_type s2 = table.find(src[i + 1]); const std::string::size_type s3 = table.find(src[i + 2]); const std::string::size_type s4 = table.find(src[i + 3]); if (s1 == std::string::npos || s2 == std::string::npos || s3 == std::string::npos || s4 == std::string::npos) { return false; } cdst.push_back(static_cast<unsigned char>(((s1 & 0x3F) << 2) | ((s2 & 0x30) >> 4))); cdst.push_back(static_cast<unsigned char>(((s2 & 0x0F) << 4) | ((s3 & 0x3C) >> 2))); cdst.push_back(static_cast<unsigned char>(((s3 & 0x03) << 6) | ((s4 & 0x3F) >> 0))); } } dst.swap(cdst); return true; } }
test.cpp
#include <iostream> #include <iomanip> #include <vector> #include "base64.hpp" int main() { std::vector<unsigned char> v1, v2; v1.push_back(0xde); v1.push_back(0xad); v1.push_back(0xbe); v1.push_back(0xef); std::string s; algorithm::encode_base64(v1, s); // base64 エンコード std::cout << s << std::endl; // 3q2+7w== algorithm::decode_base64(s, v2); // base64 デコード for (std::vector<unsigned char>::const_iterator it = v2.begin(); it != v2.end(); ++it) { std::cout << std::hex << static_cast<int>(*it); } // deadbeef return 0; }