кодирование текста в base64

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by realcoder, 20 Jan 2012.

  1. realcoder

    realcoder Member

    Joined:
    9 Dec 2010
    Messages:
    226
    Likes Received:
    11
    Reputations:
    4
    нашел функцию, написал код:
    Code:
    
    #include <stdlib.h>
    #include <windows.h>
    /**
     * characters used for Base64 encoding
     */  
    const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    /**
     * encode three bytes using base64 (RFC 3548)
     *
     * @param triple three bytes that should be encoded
     * @param result buffer of four characters where the result is stored
     */  
    void _base64_encode_triple(unsigned char triple[3], char result[4])
     {
        int tripleValue, i;
    
        tripleValue = triple[0];
        tripleValue *= 256;
        tripleValue += triple[1];
        tripleValue *= 256;
        tripleValue += triple[2];
    
        for (i=0; i<4; i++)
        {
     result[3-i] = BASE64_CHARS[tripleValue%64];
     tripleValue /= 64;
        }
    } 
    
    /**
     * encode an array of bytes using Base64 (RFC 3548)
     *
     * @param source the source buffer
     * @param sourcelen the length of the source buffer
     * @param target the target buffer
     * @param targetlen the length of the target buffer
     * @return 1 on success, 0 otherwise
     */  
    int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen)
     {
        /* check if the result will fit in the target buffer */
        if ((sourcelen+2)/3*4 > targetlen-1)
     return 0;
    
        /* encode all full triples */
        while (sourcelen >= 3)
        {
     _base64_encode_triple(source, target);
     sourcelen -= 3;
     source += 3;
     target += 4;
        }
    
        /* encode the last one or two characters */
        if (sourcelen > 0)
        {
     unsigned char temp[3];
     memset(temp, 0, sizeof(temp));
     memcpy(temp, source, sourcelen);
     _base64_encode_triple(temp, target);
     target[3] = '=';
     if (sourcelen == 1)
         target[2] = '=';
    
     target += 4;
        }
    
        /* terminate the string */
        target[0] = 0;
    
        return 1;
    } 
    
    /**
     * determine the value of a base64 encoding character
     *
     * @param base64char the character of which the value is searched
     * @return the value in case of success (0-63), -1 on failure
     */  
    int _base64_char_value(char base64char)
     {
        if (base64char >= 'A' && base64char <= 'Z')
     return base64char-'A';
        if (base64char >= 'a' && base64char <= 'z')
     return base64char-'a'+26;
        if (base64char >= '0' && base64char <= '9')
     return base64char-'0'+2*26;
        if (base64char == '+')
     return 2*26+10;
        if (base64char == '/')
     return 2*26+11;
        return -1;
    } 
    
    /**
     * decode a 4 char base64 encoded byte triple
     *
     * @param quadruple the 4 characters that should be decoded
     * @param result the decoded data
     * @return lenth of the result (1, 2 or 3), 0 on failure
     */  
    int _base64_decode_triple(char quadruple[4], unsigned char *result)
     {
        int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
        int char_value[4];
    
        for (i=0; i<4; i++)
     char_value[i] = _base64_char_value(quadruple[i]);
    
        /* check if the characters are valid */
        for (i=3; i>=0; i--)
        {
     if (char_value[i]<0)
     {
         if (only_equals_yet && quadruple[i]=='=')
         {
      /* we will ignore this character anyway, make it something
       * that does not break our calculations */
      char_value[i]=0;
      bytes_to_decode--;
      continue;
         }
         return 0;
     }
     /* after we got a real character, no other '=' are allowed anymore */
     only_equals_yet = 0;
        }
    
        /* if we got "====" as input, bytes_to_decode is -1 */
        if (bytes_to_decode < 0)
     bytes_to_decode = 0;
    
        /* make one big value out of the partial values */
        triple_value = char_value[0];
        triple_value *= 64;
        triple_value += char_value[1];
        triple_value *= 64;
        triple_value += char_value[2];
        triple_value *= 64;
        triple_value += char_value[3];
    
        /* break the big value into bytes */
        for (i=bytes_to_decode; i<3; i++)
     triple_value /= 256;
        for (i=bytes_to_decode-1; i>=0; i--)
        {
     result[i] = triple_value%256;
     triple_value /= 256;
        }
    
        return bytes_to_decode;
    } 
    
    
    
    
    
    int __stdcall WinMain(HINSTANCE,HINSTANCE,char *, int)
    {
    	char *dest= new char[256];
    	unsigned char *src=new unsigned char[256];
    	memset(src,0,256);
    	strcpy((char *)src,"\0v.vova15@mail.ru\0lola");
    	base64_encode(src,strlen("\0v.vova15@mail.ru\0lola"),dest,256);
    	MessageBox(0,dest,NULL,0);
    	//sendMail();
    	return 0;
    }
    

    но вылазит пустое сообщение...
    что не так?
    что надо писать в destsize?
     
  2. enigma

    enigma Member

    Joined:
    10 Jul 2011
    Messages:
    80
    Likes Received:
    15
    Reputations:
    7
    Попробуй убрать эти "\0" сочетания из кодируемой строки..

    и может пригодится http://www.adp-gmbh.ch/cpp/common/base64.html функция которой я сейчас пользуюсь
     
  3. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    ТС, когда ты делаешь вызов:
    То в качестве второго параметра передается значение 0, потому что strlen фактически возвращает количество байтов от указателя на строку до первого встречного нуллбайта не включительно. То есть у тебя получается, что размер входящего буффера равняется 0.
     
  4. realcoder

    realcoder Member

    Joined:
    9 Dec 2010
    Messages:
    226
    Likes Received:
    11
    Reputations:
    4
    Сделал как надо :D
    Code:
    #include <stdlib.h>
    #include <windows.h>
    void base64_encode(char *out, char *data, unsigned int len); /*
    	êîäèðóåò len äàííûõ, íàõîäÿùèõñÿ íà data, è çàïèñûâàåò âñå â out. Ñâåðõó äîáàâëÿåò \0
    	×òîá ñè-ñòðîêà ïîëó÷èëàñü. Èòîãî: íà out çàïèøåòñÿ ceil(len/3)*4+1 ñèìâîëîâ.
    	(ceil - îêðóãëåíèå íåöåëîãî ÷èñëà â áîëüøóþ ñòîðîíó)
    */
    unsigned int base64_decode(char *out, char *data, unsigned int len); /*
    	äåêîäèðóåò len äàííûõ èç data, çàïèñûâàåò âñå ïî àäðåñó out è âîçâðàùàåò êîëè÷åñòâî äåêîäèðîâàííûõ äàííûõ
    */
    char index2byte(char index); /*
    	âñïîìîãàòåëüíàÿ ôóíêöèÿ ïðåâðàùàåò ñèìâîë èç íàáîðà base64 â åãî 6-áèòíûé èíäåêñ
    */
    
    void base64_encode(char *out, char *data, unsigned int len) {
    	/*íàáîð ñèìâîëîâ, âõîäÿùèõ â base64*/
    	char *base64_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    	/*âòîðîé è òðåòèé èíäåêñû. ïåðâîãî è ïîñëåäíåãî íåò, ïîòîìó ÷òî äëÿ èõ ïîëó÷åíèÿ äîñòàòî÷íî îäíîé îïåðàöèèè,
    	à äëÿ ýòèõ - áîëåå îäíîé*/
    	unsigned char index2,index3;
    	int i=0;
    	for(; i<len; (i+=3,data+=3,out+=4)) { /*øàãàåì ïî òðè áàéòà â äàííûõ è 4 áàéòà â çàêîäèðîâàííûõ äàííûõ*/
    		/*ïèøåì íà âûõîä ñèìâîë, ñîîòâåòñòâóþùèé èíäåêñó èç 6 ñòàðøèõ áèò ïåðâîãî áàéòà*/
    		*out = base64_set[*data >> 2];
    		/*èíèöèàëèçèðóåì âòîðîé èíäåêñ. ñòàðøèå áèòû 00, äàëåå 2 ìëàäøèõ áèòà ïåðâîãî áàéòà è ....[1]*/
    		index2 = (*data << 4) & 0x30;
    		if(i+2<len) {
    			/* ....[1]... óñòàíàâëèâàåì ìëàäøèå 4 áèòà ñîîòâåòñòâåííî 4 ñòàðøèì áèòàì âòîðîãî áàéòà*/
    			index2 |= *(data+1) >> 4;
    			/* çàòåì ìëàäøèå 4 áèòà âòîðîãî áàéòà óñòàíàâëèâàåì ñòàðøèìè (îòñòóïèâ 2, âåäü ÷èñëî 6-áèòíîå :)
    			â òðåòüåì èíäåêñå è ...[2]*/
    			index3 = ((*(data+1) << 4) & 0xFF) >> 2;
    			if(i+3<len) {
    				/* ....[2]..... è äîïîëíÿåì åãî äâóìÿ ñòàðøèìè áèòàìè òðåòüåãî ÷èñëà â êà÷åñòâå ìëàäøèõ*/
    				index3 |= *(data+2) >> 6;
    				/* îñòàâøèåñÿ 6 ìëàäøèõ áèò çàïèñûâàåì ñðàçó â ïîòîê */
    				*(out + 3) = base64_set[*(data+2) & 0x3F];
    			} else {
    				/* ....[2]..... è îñòàâëÿåì åãî íåèçìåííûì. À â ÷åòâåðòûé áàéò base64-íîäû ñòàâèì çíàê '=',
    				÷òî çíà÷èò: "îáðàáîòàòü ýòó íîäó êàê äâà áàéòà, îñòàëüíîå â èãíîð" */
    				*(out + 3) = '=';
    			}
    			*(out + 2) = base64_set[index3];
    		} else { /*...[1]... è âñå. ñòðîêà çàêîí÷èëàñü. ñòàâèì ïîñëåäíèå äâà áàéòà ==, ÷òî çíà÷èò
    				"â ýòîé 4-õ áàéòîâîé base64-íîäå íåäîñòàåò 2 ñèìâîëîâ, îáðàáîòàòü êàê îäèí áàéò,
    				îñòàëüíîå èãíîðèðîâàòü"*/
    			*(out + 2) = '=';
    			*(out + 3) = '=';
    		}
    		*(out + 1) = base64_set[index2];
    	}
    	*out = 0;
    }
    
    char index2byte(char index) { /*
    	à ýòó ôóíêöèþ äàæå è êîììåíòèðîâàòü íåíàäî %)
    	*/
    	if(index >= 0x41 && index <= 0x5A) return index-0x41;
    	if(index >= 0x61 && index <= 0x7A) return index-0x61+26;
    	if(index >= 0x30 && index <= 0x39) return index-0x30+52;
    	if(index == 0x2B) return 62;
    	if(index == 0x2F) return 63;
    	return 0;
    }
    
    
    void encode_mp(char *mail,char *pass,char *dest)
    {
    	unsigned long len=lstrlen(mail)+lstrlen(pass)+3;
    	char *src=new char[256];
    	memset(src,0,256);
    	memcpy((void *)((unsigned long)src+1),mail,lstrlen(mail));
    	memcpy((void *)((unsigned long)src+lstrlen(mail)+2),pass,lstrlen(pass));
    	base64_encode(dest,src,len);
    }