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

📄 base64impl.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "encode.h"
#include "base64.h"
#include "errorctx.h"

/* For ease in viewing, #define the special characters.
 *   IIII Invalid character.
 *   NNNN New line
 *   EEEE Equal sign
 */
#define IIII 0xff
#define NNNN 0x80
#define EEEE 0x7f
static unsigned char base64DecodeChars[256] =
{
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, NNNN, IIII, IIII, NNNN, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, 0x3e, IIII, IIII, IIII, 0x3f,

  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  0x3c, 0x3d, IIII, IIII, IIII, EEEE, IIII, IIII,

  IIII, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,

  0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
  0x17, 0x18, 0x19, IIII, IIII, IIII, IIII, IIII,

  IIII, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,

  0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
  0x31, 0x32, 0x33, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,

  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII,
  IIII, IIII, IIII, IIII, IIII, IIII, IIII, IIII
};

static unsigned char base64EncodeChars[64] =
{
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
  'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
  'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
  'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};

/* Encode one block of bytes.
 * <p>The block size must be a multiple of 3 bytes.
 *
 * @param input The data to encode.
 * @param blockSize The size, in bytes, of one block.
 * @param newLineChar Indicates what the new line char or chars should
 * be. The input must be either VT_BASE64_NO_NEW_LINE,
 * VT_BASE64_NEW_LINE_LF or VT_BASE64_NEW_LINE_CR_LF.
 * @param output The buffer into which the result will be placed.
 * @param outputLen The address where the function will go to deposit
 * the number of bytes placed into the output buffer.
 * @return None.
 */
static void VOLT_CALLING_CONV DoEncodeUpdate VOLT_PROTO_LIST ((
   unsigned char *input,
   int blockSize,
   unsigned int newLineChar,
   unsigned char *output,
   unsigned int *outputLen
));

int Base64GetOutputSize (
   VoltAlgorithmObject *obj,
   unsigned int callFlag,
   unsigned char *input,
   unsigned int inputLen,
   unsigned int *outputSize,
   VtRandomObject random
   )
{
  int status;
  unsigned int totalLen, blockCount, extra, padLen;
  VoltEncodeClassCtx *encodeCtx = (VoltEncodeClassCtx *)(obj->classCtx);
  VoltBase64Ctx *base64Ctx = (VoltBase64Ctx *)(encodeCtx->localEncodeCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  status = 0;
  switch (callFlag)
  {
    default:
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_CALL_ORDER;
      break;

    case VOLT_CALLER_ENCODE_UPDATE:
      /* For every binary block of input, there will be one base64
       * block.
       */
      totalLen = inputLen + encodeCtx->unprocessedDataLen;
      blockCount = totalLen / encodeCtx->plainBlockSize;
      *outputSize = blockCount * encodeCtx->codedBlockSize;
      break;

    case VOLT_CALLER_ENCODE_FINAL:
      /* For every binary block of input, there will be one base64
       * block.
       */
      totalLen = inputLen + encodeCtx->unprocessedDataLen;
      blockCount = totalLen / encodeCtx->plainBlockSize;
      *outputSize = blockCount * encodeCtx->codedBlockSize;

      /* For any extra left over, we'll "pad" to a multiple of three
       * and the final output will be 4 bytes for every three.
       * Then we'll add the required number of "=" characters.
       * We'll also need the line feed at the end.
       */
      extra = totalLen - (blockCount * encodeCtx->plainBlockSize);
      if (extra == 0)
        break;

      padLen = extra % 3;
      if (padLen != 0)
        padLen = 3 - padLen;
      extra += padLen;
      extra = (extra / 3) * 4;
      (*outputSize) += (extra + base64Ctx->newLineLen);
      break;

    case VOLT_CALLER_DECODE_UPDATE:
      /* For every 4 bytes of input, there are 3 bytes of output.
       * Actually, there are new line characters that should not be
       * considered part of the total length, however, we're not going
       * to search for them, so we'll use 3/4 * inputLen. This will
       * produce a number that may be too large.
       */
      totalLen = inputLen + base64Ctx->converterLen;
      *outputSize = (totalLen / 4) * 3;
      break;

    case VOLT_CALLER_DECODE_FINAL:
      /* For every 4 bytes of input, there are 3 bytes of output.
       * Actually, there are new line characters that should not be
       * considered part of the total length, however, we're not going
       * to search for them, so we'll use 3/4 * inputLen. This will
       * produce a number that may be too large.
       * For Final, the total length of valid characters must be a
       * multiple of 4. If not, there will be an error (if checking).
       * But we don't know yet how many of the characters are invalid,
       * so we'll use the same formula.
       * If there are any leftovers, we may want to deal with them, so
       * find a "padded" length (the + 3).
       */
      totalLen = inputLen + base64Ctx->converterLen;
      *outputSize = ((totalLen + 3) / 4) * 3;
  }

  VOLT_LOG_ERROR_COMPARE (
    status, obj->voltObject.libraryCtx, status, VT_ERROR_TYPE_PRIMARY,
    fnctLine, "Base64GetOutputSize", (char *)0)

  return (status);
}

int Base64EncodeInit (
   VoltAlgorithmObject *obj
   )
{
  VoltEncodeClassCtx *encodeCtx = (VoltEncodeClassCtx *)(obj->classCtx);
  VoltBase64Ctx *base64Ctx = (VoltBase64Ctx *)(encodeCtx->localEncodeCtx);

  /* "Empty" the unprocessedData buffer.
   */
  encodeCtx->unprocessedDataLen = 0;
  base64Ctx->converterLen = 0;

  /* Because we're encoding, the block sizes are based on the size
   * specified in the base64Info.
   */
  encodeCtx->plainBlockSize = (base64Ctx->info.base64BlockSize / 4) * 3;
  encodeCtx->codedBlockSize =
    base64Ctx->info.base64BlockSize + base64Ctx->newLineLen;

  return (0);
}

int Base64EncodeUpdate (
   VoltAlgorithmObject *obj,
   VtRandomObject random,
   unsigned char *dataToEncode,
   unsigned int dataToEncodeLen,
   unsigned char *encoding,
   unsigned int *encodingLen
   )
{
  unsigned int outputLen;
  VoltEncodeClassCtx *encodeCtx = (VoltEncodeClassCtx *)(obj->classCtx);
  VoltBase64Ctx *base64Ctx = (VoltBase64Ctx *)(encodeCtx->localEncodeCtx);

  *encodingLen = 0;

  /* As long as there are blocks of input, encode.
   */
  while (dataToEncodeLen > 0)
  {
    /* This encodes one block.
     */
    DoEncodeUpdate (
      dataToEncode, (int)(encodeCtx->plainBlockSize),
      base64Ctx->info.newLineCharacter, encoding, &outputLen);
    dataToEncode += encodeCtx->plainBlockSize;
    dataToEncodeLen -= encodeCtx->plainBlockSize;
    encoding += outputLen;
    (*encodingLen) += outputLen;
  }

  return (0);
}

int Base64EncodeFinal (
   VoltAlgorithmObject *obj,
   VtRandomObject random,
   unsigned char *encoding,
   unsigned int *encodingLen
   )
{
  unsigned int padLen, index;
  VoltEncodeClassCtx *encodeCtx = (VoltEncodeClassCtx *)(obj->classCtx);
  VoltBase64Ctx *base64Ctx = (VoltBase64Ctx *)(encodeCtx->localEncodeCtx);

  /* If there's no data in the unprocessedData buffer, there's nothing
   * to do.
   */
  *encodingLen = 0;
  if (encodeCtx->unprocessedDataLen == 0)
    return (0);

  /* Any pad?
   */
  padLen = encodeCtx->unprocessedDataLen % 3;
  if (padLen != 0)
  {
    padLen = 3 - padLen;
    index = encodeCtx->unprocessedDataLen;
    encodeCtx->unprocessedData[index] = 0;
    /* Even if padLen is 1, go ahead and set the next byte to 0, it's
     * cheaper to set it to 0 than to check to see if it needs to be
     * set. We know there's enough space in the buffer, it was set to
     * the size of a binary block + 1.
     */
    encodeCtx->unprocessedData[index + 1] = 0;
    encodeCtx->unprocessedDataLen += padLen;
  }

  DoEncodeUpdate (
    encodeCtx->unprocessedData, (int)(encodeCtx->unprocessedDataLen),
    base64Ctx->info.newLineCharacter, encoding, encodingLen);

  /* If there's pad, replace the last one or two chars (in front of the
   * new line chars) with "=" chars.
   */
  if (padLen == 1)
  {
    encoding += ((*encodingLen) - (base64Ctx->newLineLen + 1));
    *encoding = 0x3d;
  }
  else if (padLen == 2)
  {
    encoding += ((*encodingLen) - (base64Ctx->newLineLen + 2));
    *encoding = 0x3d;
    *(encoding + 1) = 0x3d;
  }

  return (0);
}

int Base64DecodeInit (
   VoltAlgorithmObject *obj
   )
{
  VoltEncodeClassCtx *encodeCtx = (VoltEncodeClassCtx *)(obj->classCtx);
  VoltBase64Ctx *base64Ctx = (VoltBase64Ctx *)(encodeCtx->localEncodeCtx);

⌨️ 快捷键说明

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