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

📄 cs_base64.cpp

📁 c-smile 一个语法类似与JS 又有点像C++的 编译器
💻 CPP
字号:
/*
*
* cs_base64.cpp
*
* Copyright (c) 2001, 2002
* Andrew Fedoniouk - andrew@terra-informatica.org
* Portions: Serge Kuznetsov -  kuznetsov@deeptown.org
*
* See the file "COPYING" for information on usage 
* and redistribution of this file
*
*/
#include "cs_basic.h"
#include "cs_array.h"
#include "cs_string.h"

namespace tool
{
  //
  // code characters for values 0..63
  //
  static char alphabet[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

  //
  // lookup table for converting base64 characters to value in range 0..63
  //
  static signed char codes [ 256 ];
  static bool codes_empty = true;

  /**
  * returns an array of base64-encoded characters to represent the
  * passed data array.
  *
  * @param data the array of bytes to encode
  * @return base64-coded character string.
  */
  string
    base64_encode ( const byte* data, int data_length )
  {
    int     out_length = ( ( data_length + 2 ) / 3 ) * 4;
    string  out ( '\0', out_length );
    //
    // 3 bytes encode to 4 chars.  Output is always an even
    // multiple of 4 characters.
    //
    for ( int i = 0, index = 0; i < data_length; i += 3, index += 4 )
    {
      bool quad = false;
      bool trip = false;

      int val = ( 0xFF & (int) data [ i ] );
      val <<= 8;
      if ( ( i + 1 ) < data_length )
      {
        val |= ( 0xFF & (int) data [ i + 1 ] );
        trip = true;
      }
      val <<= 8;
      if ( ( i + 2 ) < data_length )
      {
        val |= ( 0xFF & (int) data [ i + 2 ] );
        quad = true;
      }
      out [ index + 3 ] = alphabet [ ( quad ? ( val & 0x3F ) : 64 ) ];
      val >>= 6;
      out [ index + 2 ] = alphabet [ ( trip ? ( val & 0x3F ) : 64 ) ];
      val >>= 6;
      out [ index + 1 ] = alphabet [ val & 0x3F ];
      val >>= 6;
      out [ index + 0 ] = alphabet [ val & 0x3F ];
    }
    return out;
  }

  /**
  * Decodes a BASE-64 encoded stream to recover the original
  * data. White space before and after will be trimmed away,
  * but no other manipulation of the input will be performed.
  *
  * As of version 1.2 this method will properly handle input
  * containing junk characters (newlines and the like) rather
  * than throwing an error. It does this by pre-parsing the
  * input and generating from that a count of VALID input
  * characters.
  **/
  bool
    base64_decode ( const char *data, int data_length, array<byte>& out )
  {
    int i;
    if ( codes_empty )
    {
      for ( i = 0; i < 256; i++ )
        codes [ i ] = -1;
      for ( i = 'A'; i <= 'Z'; i++ )
        codes [ i ] = (byte) (      i - 'A' );
      for ( i = 'a'; i <= 'z'; i++ )
        codes [ i ] = (byte) ( 26 + i - 'a' );
      for ( i = '0'; i <= '9'; i++ )
        codes [ i ] = (byte) ( 52 + i - '0' );
      codes [ '+' ] = 62;
      codes [ '/' ] = 63;
      codes_empty = false;
    }

    // as our input could contain non-BASE64 data (newlines,
    // whitespace of any sort, whatever) we must first adjust
    // our count of USABLE data so that...
    // (a) we don't misallocate the output array, and
    // (b) think that we miscalculated our data length
    //     just because of extraneous throw-away junk

    int tempLen = data_length;
    int ix;
    for( ix = 0; ix < data_length; ix++ )
    {
      if ( codes [ data [ ix ] ] < 0 )  //(data[ix] > 255) ||
        --tempLen;    // ignore non-valid chars and padding
    }
    // calculate required length:
    //  -- 3 bytes for every 4 valid base64 chars
    //  -- plus 2 bytes if there are 3 extra base64 chars,
    //     or plus 1 byte if there are 2 extra.

    int len = ( tempLen / 4 ) * 3;
    if ( ( tempLen % 4 ) == 3 )
      len += 2;
    if ( ( tempLen % 4 ) == 2 )
      len += 1;

    //byte *out = new byte [ len ];
    //memset ( out, 0, len );
    byte zero = 0;
    out.size ( len );

    int shift = 0;   // # of excess bits stored in accum
    int accum = 0;   // excess bits
    int index = 0;

    // we now go through the entire array (NOT using the 'tempLen' value)
    for ( ix = 0; ix < data_length; ix++ )
    {
      int value = ( data [ ix ] > 255 ) ? -1 : codes [ data [ ix ] ];

      if ( value >= 0 )           // skip over non-code
      {
        accum <<= 6;            // bits shift up by 6 each time thru
        shift += 6;             // loop, with new bits being put in
        accum |= value;         // at the bottom.
        if ( shift >= 8 )       // whenever there are 8 or more shifted in,
        {
          shift -= 8;         // write them out (from the top, leaving any
          out [ index++ ] =      // excess at the bottom for next iteration.
            (byte) ( ( accum >> shift ) & 0xff );
        }
      }
      // we will also have skipped processing a padding null byte ('=') here;
      // these are used ONLY for padding to an even length and do not legally
      // occur as encoded data. for this reason we can ignore the fact that
      // no index++ operation occurs in that special case: the out[] array is
      // initialized to all-zero bytes to start with and that works to our
      // advantage in this combination.
    }

    // if there is STILL something wrong we just have to return false
    return ( index == out.size () );
  }

};

⌨️ 快捷键说明

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