#include #include #include #include using namespace std; string rotbase( string sztext, char* N, bool decode); string RotN( char* szText, int N, bool decode ); static inline bool is_base64( unsigned char c ); string base64encode( const char *lpszData, unsigned long nDataLen ); string base64decode( const char *lpszData ); string Base64CharTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int main( int argc, char* argv[] ) { string encoded = rotbase(argv[1], argv[2], false); printf("Original -> %s\n", argv[1]); printf("Encoded -> %s\n",encoded.c_str()); string decoded = rotbase(encoded.substr(2), argv[2], true); printf("Decoded -> %s",decoded.c_str()); return 0; } string rotbase( string szText, char* N, bool decode ) { if(!decode) return RotN((char*)base64encode(szText.c_str(), szText.length()).c_str(), atoi(N), false).insert(0, N); else return base64decode(RotN((char*)szText.c_str(), atoi(N), true).c_str()); } string RotN( char* szText, int N, bool decode ) { string szBuf; char cap, byte; for(int i = 0; i < (int)strlen(szText); i++) { byte = szText[i]; cap = byte & 32; byte &= ~cap; if(!decode) byte = ((byte >= 'A') && (byte <= 'Z') ? ((byte - 'A' + N) % 26 + 'A') : byte) | cap; else byte = ((byte >= 'A') && (byte <= 'Z') ? ((byte + 'A' - N) % 26 + 'A') : byte) | cap; szBuf += byte; } szBuf += '\0'; return szBuf; } static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } string base64encode( const char *lpszData, unsigned long nDataLen ) { // reserve memory string sBase64; sBase64.reserve( ( nDataLen ) ); // encode unsigned long nLinePos = 0; while( nDataLen > 0 ) { unsigned long n; // get 24 bits // - get bytes available unsigned long nBytesCount; if( nDataLen >= 3 ) nBytesCount = 3; else if( nDataLen == 2 ) nBytesCount = 2; else if( nDataLen == 1 ) nBytesCount = 1; unsigned long nBase64Blocks = ceil( ( nBytesCount * 8.0 / 6.0 ) ); // - read char Bytes[ 3 ]; for( n = 0; n < nBytesCount; n++ ) Bytes[ n ] = lpszData[ n ]; lpszData += nBytesCount; nDataLen -= nBytesCount; // encode char Base64TableIndex[ 4 ]; Base64TableIndex[ 0 ] = ( Bytes[0] & 0xfc ) >> 2; Base64TableIndex[ 1 ] = ( ( Bytes[ 0 ] & 0x03 ) << 4 ) + ( ( Bytes[ 1 ] & 0xf0 ) >> 4 ); Base64TableIndex[ 2 ] = ( ( Bytes[ 1 ] & 0x0f ) << 2 ) + ( ( Bytes[ 2 ] & 0xc0 ) >> 6 ); Base64TableIndex[ 3 ] = Bytes[ 2 ] & 0x3f; for( n = 0; n < nBase64Blocks; n++ ) { sBase64.append( 1, Base64CharTable[ Base64TableIndex[ n ] ] ); nLinePos++; } // add padding for( n = nBase64Blocks; n < 4; n++ ) sBase64.append( 1, '=' ); } return sBase64; } string base64decode( const char *lpszData ) { int in_len = strlen(lpszData); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; string ret; while (in_len-- && ( lpszData[in_] != '=') && is_base64(lpszData[in_])) { char_array_4[i++] = lpszData[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) char_array_4[i] = Base64CharTable.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } } if (i) { for (j = i; j <4; j++) char_array_4[j] = 0; for (j = 0; j <4; j++) char_array_4[j] = Base64CharTable.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; } return ret; }