説明を見る。00001 #include "osl/misc/base64.h"
00002 #include "osl/book/compactBoard.h"
00003 #include <sstream>
00004 std::string osl::misc::
00005 base64Encode(boost::dynamic_bitset<> src)
00006 {
00007 if (src.empty())
00008 return "";
00009
00010 const size_t bits_to_add = 6 - src.size()%6;
00011 if (bits_to_add < 6)
00012 {
00013 for (size_t i=0; i<bits_to_add; ++i)
00014 {
00015 src.push_back(0ul);
00016 src <<= 1;
00017 }
00018 }
00019 assert(src.size()%6 == 0);
00020 assert(src.size()/6 > 0);
00021
00022 std::vector<char> dst(src.size()/6, 0);
00023 const boost::dynamic_bitset<> mask(src.size(), 63ul);
00024 for (size_t i=0; i<dst.size(); ++i)
00025 {
00026 const unsigned long c = ((src >> i*6) & mask).to_ulong();
00027 assert (c <= 63);
00028 if ( c <= 25)
00029 dst[dst.size()-1-i] = static_cast<char>(c+65);
00030 else if (26 <= c && c <= 51)
00031 dst[dst.size()-1-i] = static_cast<char>(c+97-26);
00032 else if (52 <= c && c <= 61)
00033 dst[dst.size()-1-i] = static_cast<char>(c+48-52);
00034 else if (c == 62)
00035 dst[dst.size()-1-i] = '-';
00036 else if (c == 63)
00037 dst[dst.size()-1-i] = '_';
00038 else
00039 {
00040 assert(false);
00041 return "";
00042 }
00043 }
00044
00045 const size_t char_to_add = 4 - dst.size()%4;
00046 if (char_to_add < 4)
00047 {
00048 for (size_t i=0; i<char_to_add; ++i)
00049 dst.push_back('=');
00050 }
00051
00052 return std::string(dst.begin(), dst.end());
00053 }
00054
00055 boost::dynamic_bitset<> osl::misc::
00056 base64Decode(std::string src)
00057 {
00058 if (src.empty() || src.size()%4 != 0)
00059 return boost::dynamic_bitset<>(0);
00060
00061 {
00062 int count = 0;
00063 while (src[src.size()-1] == '=')
00064 {
00065 src.erase(src.end()-1);
00066 ++count;
00067 }
00068 if (count >= 4)
00069 return boost::dynamic_bitset<>(0);
00070 }
00071
00072 const size_t dst_size = src.size()*6;
00073 const size_t redundant = dst_size%8;
00074 boost::dynamic_bitset<> dst(dst_size, 0ul);
00075 for (char c: src)
00076 {
00077 unsigned long tmp = 0;
00078 if (48 <= c && c <= 48+9)
00079 tmp = c -48+52;
00080 else if (65 <= c && c <= 65+25)
00081 tmp = c - 65;
00082 else if (97 <= c && c <= 97+25)
00083 tmp = c -97+26;
00084 else if (c == '-')
00085 tmp = 62;
00086 else if (c == '_')
00087 tmp = 63;
00088 else
00089 {
00090 assert(false);
00091 return boost::dynamic_bitset<>(0);
00092 }
00093 assert( tmp <= 63);
00094 const boost::dynamic_bitset<> mask(dst_size, tmp);
00095 dst = (dst << 6) | mask;
00096 }
00097 if (redundant > 0)
00098 {
00099 dst >>= redundant;
00100 dst.resize(dst.size()-redundant);
00101 }
00102 return dst;
00103 }
00104
00105
00106 std::string osl::misc::
00107 toBase64(const book::CompactBoard& board)
00108 {
00109 const static size_t ninteger = 41;
00110 const static size_t integer_size = 32;
00111 const static size_t size = ninteger*integer_size;
00112
00113 std::stringstream ss;
00114 ss << board;
00115
00116 ss.clear();
00117 ss.seekg(0, std::ios::beg);
00118
00119 boost::dynamic_bitset<> bits(size);
00120
00121 for (size_t i = 0; i < ninteger; ++i)
00122 {
00123 const unsigned int tmp = static_cast<unsigned int>(book::readInt(ss));
00124 const boost::dynamic_bitset<> mask(size, static_cast<unsigned long>(tmp));
00125 bits = (bits << integer_size) | mask;
00126 }
00127
00128 return misc::base64Encode(bits);
00129 }
00130
00131 osl::book::CompactBoard osl::misc::
00132 toCompactBoard(const std::string& str)
00133 {
00134 const boost::dynamic_bitset<> bits = misc::base64Decode(str);
00135 std::stringstream ss;
00136 assert(bits.size()%32 == 0);
00137 const boost::dynamic_bitset<> mask(bits.size(), 4294967295ul);
00138 for (size_t i=0; i<bits.size()/32; ++i)
00139 {
00140 const unsigned long tmp = ((bits >> ((bits.size()/32-1-i)*32)) & mask).to_ulong();
00141 book::writeInt(ss, static_cast<int>(tmp));
00142 }
00143
00144 ss.clear();
00145 ss.seekg(0, std::ios::beg);
00146
00147 book::CompactBoard cb;
00148 ss >> cb;
00149 return cb;
00150 }
00151
00152
00153
00154
00155