⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdfs_base64.c

📁 文件系统源代码!!!!! 文件系统源代码
💻 C
字号:
/*** Copyright (C) 2008 Happy Fish / YuQing** FastDFS may be copied only under the terms of the GNU General* Public License V3, which may be found in the FastDFS source kit.* Please visit the FastDFS Home Page http://www.csource.org/ for more detail.**/#include <time.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include "fdfs_base64.h"static char line_separator[16];static int line_sep_len;/*** max chars per line, excluding line_separator.  A multiple of 4.*/static int line_length = 72;/*** letter of the alphabet used to encode binary values 0..63*/static unsigned char valueToChar[64];/*** binary value encoded by a given letter of the alphabet 0..63*/static int charToValue[256];static int pad_ch;/*** Marker value for chars we just ignore, e.g. \n \r high ascii*/#define IGNORE  -1/*** Marker for = trailing pad*/#define PAD   -2/*** determines how long the lines are that are generated by encode.* Ignored by decode.* @param length 0 means no newlines inserted. Must be a multiple of 4.*/void base64_set_line_length(const int length){    line_length = (length / 4) * 4;}/**    * How lines are separated.    * Ignored by decode.    * @param line_separator may be "" but not null.    * Usually contains only a combination of chars \n and \r.    * Could be any chars not in set A-Z a-z 0-9 + /.*/void base64_set_line_separator(const char *pLineSeparator){    line_sep_len = snprintf(line_separator, sizeof(line_separator), \                           "%s", pLineSeparator);}void base64_init_ex(const int nLineLength, const unsigned char chPlus, \                    const unsigned char chSplash, const unsigned char chPad){      int i;      line_length = nLineLength;      line_separator[0] = '\n';      line_separator[1] = '\0';      line_sep_len = 1;      // build translate valueToChar table only once.      // 0..25 -> 'A'..'Z'      for (i=0; i<=25; i++)      {         valueToChar[i] = (char)('A'+i);      }      // 26..51 -> 'a'..'z'      for (i=0; i<=25; i++ )      {         valueToChar[i+26] = (char)('a'+i);      }      // 52..61 -> '0'..'9'      for (i=0; i<=9; i++ )      {         valueToChar[i+52] = (char)('0'+i);      }      valueToChar[62] = chPlus;      valueToChar[63] = chSplash;      // build translate charToValue table only once.      for (i=0; i<256; i++ )      {         charToValue[i] = IGNORE;  // default is to ignore      }      for (i=0; i<64; i++ )      {         charToValue[valueToChar[i]] = i;      }      pad_ch = chPad;      charToValue[chPad] = PAD;}int base64_get_encode_length(const int nSrcLen){   // Each group or partial group of 3 bytes becomes four chars   // covered quotient   int outputLength;   outputLength = ((nSrcLen + 2) / 3) * 4;   // account for trailing newlines, on all but the very last line   if ( line_length != 0 )   {       int lines =  (outputLength + line_length - 1)/ line_length - 1;       if ( lines > 0 )       {          outputLength += lines  * line_sep_len;       }   }   return outputLength;}   /**    * Encode an arbitrary array of bytes as base64 printable ASCII.    * It will be broken into lines of 72 chars each.  The last line is not    * terminated with a line separator.    * The output will always have an even multiple of data characters,    * exclusive of \n.  It is padded out with =.    */char *base64_encode_ex(char *src, const int nSrcLen, char *dest, \                       int *dest_len, const bool bPad){  int linePos;  int leftover;  int combined;  char *pDest;  int c0, c1, c2, c3;  unsigned char *pRaw;  unsigned char *pEnd;  char *ppSrcs[2];  int lens[2];  char szPad[3];  int k;  int loop;  if (nSrcLen <= 0)  {       *dest = '\0';       *dest_len = 0;       return dest;  }  linePos = 0;  lens[0] = (nSrcLen / 3) * 3;  lens[1] = 3;  leftover = nSrcLen - lens[0];  ppSrcs[0] = src;  ppSrcs[1] = szPad;  szPad[0] = szPad[1] = szPad[2] = '\0';  switch (leftover)  {      case 0:      default:           loop = 1;           break;      case 1:           loop = 2;           szPad[0] = src[nSrcLen-1];           break;      case 2:           loop = 2;           szPad[0] = src[nSrcLen-2];           szPad[1] = src[nSrcLen-1];           break;  }  pDest = dest;  for (k=0; k<loop; k++)  {      pEnd = (unsigned char *)ppSrcs[k] + lens[k];      for (pRaw=(unsigned char *)ppSrcs[k]; pRaw<pEnd; pRaw+=3)      {         // Start a new line if next 4 chars won't fit on the current line         // We can't encapsulete the following code since the variable need to         // be local to this incarnation of encode.         linePos += 4;         if (linePos > line_length)         {            if ( line_length != 0 )            {               memcpy(pDest, line_separator, line_sep_len);               pDest += line_sep_len;            }            linePos = 4;         }         // get next three bytes in unsigned form lined up,         // in big-endian order         combined = ((*pRaw) << 16) | ((*(pRaw+1)) << 8) | (*(pRaw+2));         // break those 24 bits into a 4 groups of 6 bits,         // working LSB to MSB.         c3 = combined & 0x3f;         combined >>= 6;         c2 = combined & 0x3f;         combined >>= 6;         c1 = combined & 0x3f;         combined >>= 6;         c0 = combined & 0x3f;         // Translate into the equivalent alpha character         // emitting them in big-endian order.         *pDest++ = valueToChar[c0];         *pDest++ = valueToChar[c1];         *pDest++ = valueToChar[c2];         *pDest++ = valueToChar[c3];      }  }  *pDest = '\0';  *dest_len = pDest - dest;  // deal with leftover bytes  switch (leftover)  {     case 0:     default:        // nothing to do        break;     case 1:        // One leftover byte generates xx==        if (bPad)        {           *(pDest-1) = pad_ch;           *(pDest-2) = pad_ch;        }        else        {           *(pDest-2) = '\0';           *dest_len -= 2;        }        break;     case 2:        // Two leftover bytes generates xxx=        if (bPad)        {           *(pDest-1) = pad_ch;        }        else        {           *(pDest-1) = '\0';           *dest_len -= 1;        }        break;  } // end switch;  return dest;}char *base64_decode_auto(char *src, const int nSrcLen, \		char *dest, int *dest_len){	int nRemain;	int nPadLen;	int nNewLen;	char tmpBuff[256];	char *pBuff;	nRemain = nSrcLen % 4;	if (nRemain == 0)	{		return base64_decode(src, nSrcLen, dest, dest_len);	}	nPadLen = 4 - nRemain;	nNewLen = nSrcLen + nPadLen;	if (nNewLen <= sizeof(tmpBuff))	{		pBuff = tmpBuff;	}	else	{		pBuff = (char *)malloc(nNewLen);		if (pBuff == NULL)		{			fprintf(stderr, "Can't malloc %d bytes\n", \				nSrcLen + nPadLen + 1);			*dest_len = 0;			*dest = '\0';			return dest;		}	}	memcpy(pBuff, src, nSrcLen);	memset(pBuff + nSrcLen, pad_ch, nPadLen);	base64_decode(pBuff, nNewLen, dest, dest_len);	if (pBuff != tmpBuff)	{		free(pBuff);	}	return dest;}/*** decode a well-formed complete base64 string back into an array of bytes.* It must have an even multiple of 4 data characters (not counting \n),* padded out with = as needed.*/char *base64_decode(char *src, const int nSrcLen, \                       char *dest, int *dest_len){      // tracks where we are in a cycle of 4 input chars.      int cycle;      // where we combine 4 groups of 6 bits and take apart as 3 groups of 8.      int combined;      // will be an even multiple of 4 chars, plus some embedded \n      int dummies;      int value;      unsigned char *pSrc;      unsigned char *pSrcEnd;      char *pDest;      cycle = 0;      combined = 0;      dummies = 0;      pDest = dest;      pSrcEnd = (unsigned char *)src + nSrcLen;      for (pSrc=(unsigned char *)src; pSrc<pSrcEnd; pSrc++)      {         value = charToValue[*pSrc];         switch (value)         {            case IGNORE:               // e.g. \n, just ignore it.               break;            case PAD:               value = 0;               dummies++;               // fallthrough            default:               /* regular value character */               switch (cycle)               {                  case 0:                     combined = value;                     cycle = 1;                     break;                  case 1:                     combined <<= 6;                     combined |= value;                     cycle = 2;                     break;                  case 2:                     combined <<= 6;                     combined |= value;                     cycle = 3;                     break;                  case 3:                     combined <<= 6;                     combined |= value;                     // we have just completed a cycle of 4 chars.                     // the four 6-bit values are in combined in big-endian order                     // peel them off 8 bits at a time working lsb to msb                     // to get our original 3 8-bit bytes back                     *pDest++ = (char)(combined >> 16);                     *pDest++ = (char)((combined & 0x0000FF00) >> 8);                     *pDest++ = (char)(combined & 0x000000FF);                     cycle = 0;                     break;               }               break;         }      } // end for      if (cycle != 0)      {         *dest = '\0';         *dest_len = 0;         fprintf(stderr, "Input to decode not an even multiple of 4 characters; pad with %c\n", pad_ch);         return dest;      }      *dest_len = (pDest - dest) - dummies;      *(dest + (*dest_len)) = '\0';      return dest;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -