📄 base64.c
字号:
/* * $Id: Base64.C,v 1.5 2000/08/17 14:58:45 evgeny Exp $ * * Copyright (c) 1994 HAL Computer Systems International, Ltd. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include "Base64.h"#include <hgl/StringC.h>#include <hgl/CharC.h>#include <hgl/SysErr.h>#include <hgl/HalAppC.h>#include <unistd.h>#include <errno.h>/* * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore) * * Permission to use, copy, modify, and distribute this material * for any purpose and without fee is hereby granted, provided * that the above copyright notice and this permission notice * appear in all copies, and that the name of Bellcore not be * used in advertising or publicity pertaining to this * material without the specific, prior written permission * of an authorized representative of Bellcore. BELLCORE * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY * OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. */#define LF_CHAR (char)10#define CR_CHAR (char)13/* * When text is encoded, LF is converted to CRLF. * When text is decoded, CRLF is converted to LF. * When non-text is encoded or decoded, no conversion is done. */static Boolean IsText = False;static Boolean CRpending = False;//*************************************************************************//// Lookup table for encoding//static char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";/*------------------------------------------------------------------------- * Encode 3 ints and write 4 int result to a file * * i1 = aabbccdd * i2 = eeffgghh * i3 = iijjkkll * * o1 = ..aabbcc * o2 = ..ddeeff * o3 = ..gghhii * o4 = ..jjkkll */inline BooleanEncode64(u_int buffer[3], FILE *fp){ u_int o1 = (buffer[0] >> 2); u_int o2 = ((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xf0) >> 4); u_int o3 = ((buffer[1] & 0x0f) << 2) | ((buffer[2] & 0xC0) >> 6); u_int o4 = (buffer[2] & 0x3f);#if 0 if ( debuglev > 1 ) cout <<"(" <<hex(buffer[0],2) <<" " <<hex(buffer[1],2) <<" " <<hex(buffer[2],2) <<") (" <<hex(o1,2) <<" " <<hex(o2,2) <<" " <<hex(o3,2) <<" " <<hex(o4,2) <<") (" <<hex(basis_64[o1],2) <<" " <<hex(basis_64[o2],2) <<" " <<hex(basis_64[o3],2) <<" " <<hex(basis_64[o4],2) <<")" <<endl;#endif return ( putc(basis_64[o1], fp) != EOF && putc(basis_64[o2], fp) != EOF && putc(basis_64[o3], fp) != EOF && putc(basis_64[o4], fp) != EOF );} // End Encode64/*------------------------------------------------------------------------- * Encode 1 or 2 ints and write 4 int result to a file. */inline BooleanEncode64(u_int *buffer, int bufsize, FILE *fp){//// Buffer size equals 1 or 2// if ( bufsize == 1 ) buffer[1] = 0; int o1 = (buffer[0] >> 2); int o2 = ((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xf0) >> 4); int o3 = (buffer[1] & 0x0f) << 2;//// Write first 2 words// Boolean error; error = (putc(basis_64[o1], fp) == EOF || putc(basis_64[o2], fp) == EOF);//// Write 3rd word if necessary or padding// if ( !error ) { if ( bufsize == 2 ) error = (putc(basis_64[o3], fp) == EOF); else error = (putc('=', fp) == EOF); }//// Write final padding// if ( !error ) error = (putc('=', fp) == EOF); return !error;} // End Encode64/*------------------------------------------------------------------------- * Encode 3 ints and add 4 int result to a string * * i1 = aabbccdd * i2 = eeffgghh * i3 = iijjkkll * * o1 = ..aabbcc * o2 = ..ddeeff * o3 = ..gghhii * o4 = ..jjkkll */inline voidEncode64(u_int buffer[3], StringC *str){ u_int o1 = (buffer[0] >> 2); u_int o2 = ((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xf0) >> 4); u_int o3 = ((buffer[1] & 0x0f) << 2) | ((buffer[2] & 0xC0) >> 6); u_int o4 = (buffer[2] & 0x3f);#if 0 if ( debuglev > 1 ) cout <<"(" <<hex(buffer[0],2) <<" " <<hex(buffer[1],2) <<" " <<hex(buffer[2],2) <<") (" <<hex(o1,2) <<" " <<hex(o2,2) <<" " <<hex(o3,2) <<" " <<hex(o4,2) <<") (" <<hex(basis_64[o1],2) <<" " <<hex(basis_64[o2],2) <<" " <<hex(basis_64[o3],2) <<" " <<hex(basis_64[o4],2) <<")" <<endl;#endif *str += basis_64[o1]; *str += basis_64[o2]; *str += basis_64[o3]; *str += basis_64[o4];} // End Encode64/*------------------------------------------------------------------------- * Encode 1 or 2 ints and add 4 int result to a string. */inline voidEncode64(u_int *buffer, int bufsize, StringC *str){//// Buffer size equals 1 or 2// if ( bufsize == 1 ) buffer[1] = 0; int o1 = (buffer[0] >> 2); int o2 = ((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xf0) >> 4); int o3 = (buffer[1] & 0x0f) << 2;//// Write first 2 words// *str += basis_64[o1]; *str += basis_64[o2];//// Write 3rd word if necessary or padding// if ( bufsize == 2 ) *str += basis_64[o3]; else *str += '=';//// Write final padding// *str += '=';} // End Encode64/*------------------------------------------------------------------------- * Function to encode a character array and place the base-64 encoded output * in a string */BooleanTextToText64(CharC istr, StringC *ostr, Boolean isText, Boolean breakLines){ Boolean LFpending = False; u_int buffer[3]; int bufsize = 0; int linesize = 0; for (int i=0; i<istr.Length(); i++) {//// Add this character to the buffer. If this is text, convert LF to CRLF// if ( isText ) { if ( LFpending ) { LFpending = False; buffer[bufsize] = LF_CHAR; i--; // Read current character again later } else { buffer[bufsize] = (u_char)istr[i]; if ( buffer[bufsize] == '\n' ) { LFpending = True; buffer[bufsize] = CR_CHAR; } } } else buffer[bufsize] = (u_char)istr[i]; bufsize++;//// Process the buffer if it is full// if ( bufsize == 3 ) { Encode64(buffer, ostr);//// Add a newline if necessary// linesize += 4; if ( breakLines && linesize > 71 ) { *ostr += '\n'; linesize = 0; } bufsize = 0; } // End if buffer is full } // End for each input character//// Write out any partial buffer.// if ( bufsize > 0 ) { Encode64(buffer, bufsize, ostr); linesize += 4; } // End if there is a partial buffer//// Add a final newline if necessary// if ( breakLines && linesize > 0 ) *ostr += '\n'; return True;} // End TextToText64/*------------------------------------------------------------------------- * Function to encode a file and place the base-64 encoded * output in a file */BooleanFileToFile64(const char *ifile, const char *ofile, Boolean isText, FILE *ifp, FILE *ofp, u_int offset, u_int length){ Boolean LFpending = False; Boolean closeInput = (ifp == NULL); Boolean closeOutput = (ofp == NULL); if ( !ifp ) {//// Open input file// ifp = fopen(ifile, "r"); if ( !ifp ) { StringC errmsg("Could not open file \""); errmsg += ifile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; }//// Initialize length// if ( length == 0 ) { fseek(ifp, 0, SEEK_END); length = (u_int)ftell(ifp); } } // End if input file is not open//// Move to offset in input file// if ( fseek(ifp, offset, SEEK_SET) != 0 ) { StringC errmsg("Could not seek to offset "); errmsg += (int)offset; errmsg += " in input file "; errmsg += ifile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; } if ( !ofp ) {//// Create an output file// ofp = fopen(ofile, "w+"); if ( !ofp ) { StringC errmsg("Could not create file \""); errmsg += ofile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; } } // End if output file is not open//// Loop through each input character// Boolean error = False; u_int buffer[3]; int bufsize = 0; int linesize = 0; int c; while ( !error && length>0 && (c=getc(ifp)) != EOF ) { length--;//// Add this character to the buffer. If this is text, convert LF to CRLF// if ( isText ) { if ( LFpending ) { LFpending = False; buffer[bufsize] = LF_CHAR; ungetc(c, ifp); // Read current character again later length++; // Reset length left to read } else { buffer[bufsize] = (u_char)c; if ( buffer[bufsize] == '\n' ) { LFpending = True; buffer[bufsize] = CR_CHAR; } } } else buffer[bufsize] = (u_char)c; bufsize++;//// Process the buffer if it is full// if ( bufsize == 3 ) { error = !Encode64(buffer, ofp);//// Add a newline if necessary// linesize += 4; if ( !error && linesize > 71 ) { error = (putc('\n', ofp) == EOF); linesize = 0; } bufsize = 0; } // End if buffer is full } // End for each input character//// Handle trailing newline in text mode// if (LFpending) { buffer[bufsize] = LF_CHAR; bufsize++; }//// Write out any partial buffer.// if ( !error && bufsize > 0 ) { error = !Encode64(buffer, bufsize, ofp); linesize += 4; } // End if there is a partial buffer//// Add a final newline if necessary// if ( !error && linesize > 0 ) error = (putc('\n', ofp) == EOF); if ( error ) { StringC errmsg("Could not write file \""); errmsg += ofile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); } else if ( c == EOF && length > 0 ) { StringC errmsg("Unexpected end of file \""); errmsg += ifile; errmsg += "\" while Base64 encoding.\n"; errmsg += "Expected "; errmsg += (int)length; errmsg += " more byte"; if ( length > 1 ) errmsg += 's'; errmsg += '.'; halApp->PopupMessage(errmsg); error = True; } if ( closeInput ) fclose(ifp); if ( closeOutput ) fclose(ofp); return !error;} // End FileToFile64/*------------------------------------------------------------------------- * Function to encode a character array and place the base-64 encoded output * in a file */BooleanTextToFile64(CharC istr, const char *ofile, Boolean isText, Boolean breakLines, FILE *ofp){ Boolean LFpending = False; Boolean closeOutput = (ofp == NULL); if ( !ofp ) {//// Create an output file// ofp = fopen(ofile, "w+"); if ( !ofp ) { StringC errmsg("Could not create file \""); errmsg += ofile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } } // End if output file is not open Boolean error = False; u_int buffer[3]; int bufsize = 0; int linesize = 0; for (int i=0; !error && i<istr.Length(); i++) {//// Add this character to the buffer. If this is text, convert LF to CRLF// if ( isText ) { if ( LFpending ) { LFpending = False; buffer[bufsize] = LF_CHAR; i--; // Read current character again later } else { buffer[bufsize] = (u_char)istr[i]; if ( buffer[bufsize] == '\n' ) { LFpending = True; buffer[bufsize] = CR_CHAR; } } } else buffer[bufsize] = (u_char)istr[i]; bufsize++;//// Process the buffer if it is full// if ( bufsize == 3 ) { error = !Encode64(buffer, ofp);//// Add a newline if necessary// linesize += 4; if ( !error && breakLines && linesize > 71 ) { error = (putc('\n', ofp) == EOF); linesize = 0; } bufsize = 0; } // End if buffer is full } // End for each input character//// Handle trailing newline in text mode// if (LFpending) { buffer[bufsize] = LF_CHAR; bufsize++; }//// Write out any partial buffer.// if ( !error && bufsize > 0 ) { error = !Encode64(buffer, bufsize, ofp); linesize += 4; } // End if there is a partial buffer//// Add a final newline if necessary// if ( !error && breakLines && linesize > 0 ) error = (putc('\n', ofp) == EOF); if ( error ) { StringC errmsg("Could not write file \""); errmsg += ofile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); } if ( closeOutput ) fclose(ofp); return !error;} // End TextToFile64/*------------------------------------------------------------------------- * Function to encode a file and place the base-64 encoded * output in a text string */BooleanFileToText64(const char *ifile, StringC *ostr, Boolean isText, FILE *ifp, u_int offset, u_int length){ Boolean LFpending = False; Boolean closeInput = (ifp == NULL); if ( !ifp ) {//// Open input file// ifp = fopen(ifile, "r"); if ( !ifp ) { StringC errmsg("Could not open file \""); errmsg += ifile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; }//// Initialize length// if ( length == 0 ) { fseek(ifp, 0, SEEK_END); length = (u_int)ftell(ifp); } } // End if input file is not open//// Move to offset in input file// if ( fseek(ifp, offset, SEEK_SET) != 0 ) { StringC errmsg("Could not seek to offset "); errmsg += (int)offset; errmsg += " in input file "; errmsg += ifile; errmsg += "\" for Base64 encoding.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; }//// Loop through each input character// u_int buffer[3]; int bufsize = 0; int linesize = 0; int c; while ( length>0 && (c=getc(ifp)) != EOF ) { length--;//// Add this character to the buffer. If this is text, convert LF to CRLF// if ( isText ) { if ( LFpending ) { LFpending = False; buffer[bufsize] = LF_CHAR; ungetc(c, ifp); // Read current character again later length++; // Reset count of characters to read } else { buffer[bufsize] = (u_char)c; if ( buffer[bufsize] == '\n' ) { LFpending = True; buffer[bufsize] = CR_CHAR; } } } else buffer[bufsize] = (u_char)c; bufsize++;//// Process the buffer if it is full
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -