Soyez le premier à donner votre avis sur cette source.
Vue 10 468 fois - Téléchargée 676 fois
/////////////////////BASE64.HPP///////////////////// #ifndef __ENCODING_BASE64_HPP__ #define __ENCODING_BASE64_HPP__ #include <iostream> /// Base64 alphabet static const std::string b64table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; class Base64 { private : /// Filling character static const char fillchar = '='; // The masks static const uint32_t mask1 = 0xFC000000; static const uint32_t mask2 = 0x03F00000; static const uint32_t mask3 = 0x000FC000; static const uint32_t mask4 = 0x00003F00; typedef union { uint32_t l ; char c[4]; }un32; public: static std::string encode(const std::string & data); static std::string decode(const std::string & data); }; #endif //////////////////////////////////////////////////// /////////////////////BASE64.CPP///////////////////// #include <base64.hpp> using namespace std; string Base64::encode(const std::string & data) { const size_t trail = data.size()%3; size_t sz = data.size()/3*4; sz += (trail != 0) ? 4 : 0; un32 b64; string out; out.resize(sz); size_t i = 0, k = 0; while(i < data.size()-trail) { b64.c[3] = data[i++]; b64.c[2] = data[i++]; b64.c[1] = data[i++]; out[k++] = b64table[static_cast <int> ((b64.l & mask1) >> 26)]; out[k++] = b64table[static_cast <int> ((b64.l & mask2) >> 20)]; out[k++] = b64table[static_cast <int> ((b64.l & mask3) >> 14)]; out[k++] = b64table[static_cast <int> ((b64.l & mask4) >> 8)]; } b64.l = 0; switch(trail) { case 1: b64.c[3] = data[i++]; out[k++] = b64table[static_cast <int> ((b64.l & mask1) >> 26)]; out[k++] = b64table[static_cast <int> ((b64.l & mask2) >> 20)]; out[k++] = fillchar; out[k++] = fillchar; break; case 2: b64.c[3] = data[i++]; b64.c[2] = data[i++]; out[k++] = b64table[static_cast <int> ((b64.l & mask1) >> 26)]; out[k++] = b64table[static_cast <int> ((b64.l & mask2) >> 20)]; out[k++] = b64table[static_cast <int> ((b64.l & mask3) >> 14)]; out[k++] = fillchar; break; } return out; } string Base64::decode(const std::string & data) { // Number of trailing '=' const size_t trail = (data[data.size()-1] == fillchar) ? ((data[data.size()-2] == fillchar) ? 2 : 1 ) : 0; // Number of char to decode const size_t szin = (trail == 0) ? data.size() : data.size()-4; // Output string size const size_t szout = szin/4*3+ ((trail == 0)? 0 : ((trail == 1) ? 3 : 2)); un32 b64; string out; out.resize(szout); size_t i = 0, k = 0; while(i < szin) { b64.l = 0; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 26; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 20; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 14; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 8; out[k++] = b64.c[3]; out[k++] = b64.c[2]; out[k++] = b64.c[1]; } b64.l = 0; switch(trail) { case 1: b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 26; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 20; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 14; out[k++] = b64.c[3]; out[k++] = b64.c[2]; break; case 2: b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 26; b64.l += (static_cast < uint32_t > (b64table.find_first_of(data[i++])) ) << 20; out[k++] = b64.c[3]; break; } return out; } ////////////////////////////////////////////////////
7 oct. 2008 à 14:36
Il fonctionne bien à deux petits bugs près:
base64.cpp Ligne 100 : dans le decodeur base 64, remplacer la ligne:
const size_t szout szin/4*3+ ((trail 0)? 0 : ((trail == 1) ? 3 : 2));
par la ligne:
const size_t szout szin/4*3+ ((trail 0)? 0 : ((trail == 1) ? 2 : 1));
Sinon, un caractère supplémentaire non initialisé est ajouté au buffer.
uuencoding.cpp Ligne 6 : remplacer
#define SPtoBACKQ(x) (x == 32) ? 96 : x
par:
#define SPtoBACKQ(x) (x)
En effet, le fait de remplacer systématiquement les blancs par des accents graves n'est pas une bonne idée car le même caractère est utilisé pour le padding en fin de ligne.
Par exemple la chaîne "LA CONSTITUTION Française " est codée avec deux accents graves à la fin plutôt que espace+accent grave. Lors du décodage on obtient une chaîne trop courte d'un caractère!
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.