base64編碼、解碼的C語言實現

來源:互聯網
上載者:User

  base64是一種基於64個可列印字元來表示位元據的表示方法。由於26=64,所以每6位為一個單位,對應某個可列印字元。三個位元組共24位,對應於4個base64單位,即3個位元組需要用4個可列印字元來表示。它常用來作為電子郵件的傳輸編碼。在base64中的可列印字元包括大寫英文字母A-Z,小寫英文字母a-z、阿拉伯數字0-9,這樣共有62個字元,此外兩個可列印符號在不同的系統中而不同,通常用加號(+)和正斜杠(/)。外加“補全符號”,通常用等號(=)。

  完整的base64定義可見RFC 1421和RFC 2045。編碼後的資料比未經處理資料略長,為原來的4/3。在電子郵件中,根據RFC 822的規定,每76個字元,還需要加上斷行符號符和分行符號。可以估算編碼後資料長度大約為原長的135.1%。

  base64編碼的時候,將三個自己的資料,先後放入一個24位的緩衝區中,先來的自己占高位。資料不足3個位元組的話,在緩衝區中剩下的位用0補足。然後,每次取出6(因為26=64)位,按照其值選擇 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 中的字元作為編碼後的輸出。不斷進行,直到全部輸入資料轉換完成。如果最後剩下兩個輸入資料,在編碼結果後加1個“=”;如果最後剩下一個輸入資料,編碼結果後加2個“=”;如果沒有剩下任何資料,就什麼都不要加。這樣才可以保證資料還原的正確性。

  C語言原始碼如下:

/** *  base64編碼、解碼實現 *       C語言原始碼 * *             葉劍飛 * *  * *    使用說明: *        命令列參數說明:若有“-d”參數,則為base64解碼,否則為base64編碼。 *        輸入來自標準輸入stdin,輸出為標準輸出stdout。可重新導向輸入輸出資料流。 * *        base64編碼:輸入任意二進位流,讀取到檔案讀完了為止(鍵盤輸入則遇到檔案結尾符為止)。 *                    輸出純文字的base64編碼。 * *        base64解碼:輸入純文字的base64編碼,讀取到檔案讀完了為止(鍵盤輸入則遇到檔案結尾符為止)。 *                    輸出原來的二進位流。 * */#include <stdio.h>#include <stdlib.h>#include <string.h>const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";char * base64_encode( const unsigned char * bindata, char * base64, int binlength ){    int i, j;    unsigned char current;    for ( i = 0, j = 0 ; i < binlength ; i += 3 )    {        current = (bindata[i] >> 2) ;        current &= (unsigned char)0x3F;        base64[j++] = base64char[(int)current];        current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;        if ( i + 1 >= binlength )        {            base64[j++] = base64char[(int)current];            base64[j++] = '=';            base64[j++] = '=';            break;        }        current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );        base64[j++] = base64char[(int)current];        current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;        if ( i + 2 >= binlength )        {            base64[j++] = base64char[(int)current];            base64[j++] = '=';            break;        }        current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );        base64[j++] = base64char[(int)current];        current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;        base64[j++] = base64char[(int)current];    }    base64[j] = '\0';    return base64;}int base64_decode( const char * base64, unsigned char * bindata ){    int i, j;    unsigned char k;    unsigned char temp[4];    for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )    {        memset( temp, 0xFF, sizeof(temp) );        for ( k = 0 ; k < 64 ; k ++ )        {            if ( base64char[k] == base64[i] )                temp[0]= k;        }        for ( k = 0 ; k < 64 ; k ++ )        {            if ( base64char[k] == base64[i+1] )                temp[1]= k;        }        for ( k = 0 ; k < 64 ; k ++ )        {            if ( base64char[k] == base64[i+2] )                temp[2]= k;        }        for ( k = 0 ; k < 64 ; k ++ )        {            if ( base64char[k] == base64[i+3] )                temp[3]= k;        }        bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |                ((unsigned char)((unsigned char)(temp[1]>>4)&0x03));        if ( base64[i+2] == '=' )            break;        bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |                ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));        if ( base64[i+3] == '=' )            break;        bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |                ((unsigned char)(temp[3]&0x3F));    }    return j;}int main(int argc, char * argv[]){    int i;    unsigned char bindata[2050];    char base64[4096];    size_t bytes;    if ( argc == 1 )    {        // encode        while ( !feof( stdin ) )        {            bytes = fread( bindata, 1, 2049, stdin );            base64_encode( bindata, base64, bytes );            printf( "%s", base64 );        }    }    else if ( argc == 2 && !strcmp(argv[1], "-d") )    {        // decode        while ( !feof( stdin ) )        {            for ( i = 0 ; i < 2048 ; i ++ )            {                base64[i] = getchar();                if ( base64[i] == EOF )                    break;                else if ( base64[i] == '\n' || base64[i] == '\r' )                    i --;            }            bytes = base64_decode( base64, bindata );            fwrite( bindata, bytes, 1, stdout );        }    }    else    {        fprintf( stderr, "Usage: %s [-d]\n\t-d\tdecode data\n\n", argv[0] );        return EXIT_FAILURE;    }    return EXIT_SUCCESS;}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.