base64.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:6k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FILE:   base64.c
  3.  * AUTHOR: Colin Perkins
  4.  *
  5.  * MIME base64 encoder/decoder described in rfc1521. This code is derived
  6.  * from version 2.7 of the Bellcore metamail package.
  7.  *
  8.  * Copyright (c) 1998-2000 University College London
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, is permitted provided that the following conditions 
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions and the following disclaimer.
  16.  * 2. Redistributions in binary form must reproduce the above copyright
  17.  *    notice, this list of conditions and the following disclaimer in the
  18.  *    documentation and/or other materials provided with the distribution.
  19.  * 3. All advertising materials mentioning features or use of this software
  20.  *    must display the following acknowledgement:
  21.  *      This product includes software developed by the Computer Science
  22.  *      Department at University College London
  23.  * 4. Neither the name of the University nor of the Department may be used
  24.  *    to endorse or promote products derived from this software without
  25.  *    specific prior written permission.
  26.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  *
  38.  * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
  39.  * 
  40.  * Permission to use, copy, modify, and distribute this material 
  41.  * for any purpose and without fee is hereby granted, provided 
  42.  * that the above copyright notice and this permission notice 
  43.  * appear in all copies, and that the name of Bellcore not be 
  44.  * used in advertising or publicity pertaining to this 
  45.  * material without the specific, prior written permission 
  46.  * of an authorized representative of Bellcore.  BELLCORE 
  47.  * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY 
  48.  * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", 
  49.  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  50.  * 
  51.  */
  52. #include "config_unix.h"
  53. #include "config_win32.h"
  54. #include "debug.h"
  55. #include "base64.h"
  56. static unsigned char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  57. int base64encode(const unsigned char *input, int input_length, unsigned char *output, int output_length)
  58. {
  59. int i = 0, j = 0;
  60. int pad;
  61. ASSERT(output_length >= (input_length * 4 / 3));
  62. while (i < input_length) {
  63. pad = 3 - (input_length - i);
  64. if (pad == 2) {
  65. output[j  ] = basis_64[input[i]>>2];
  66. output[j+1] = basis_64[(input[i] & 0x03) << 4];
  67. output[j+2] = '=';
  68. output[j+3] = '=';
  69. } else if (pad == 1) {
  70. output[j  ] = basis_64[input[i]>>2];
  71. output[j+1] = basis_64[((input[i] & 0x03) << 4) | ((input[i+1] & 0xf0) >> 4)];
  72. output[j+2] = basis_64[(input[i+1] & 0x0f) << 2];
  73. output[j+3] = '=';
  74. } else{
  75. output[j  ] = basis_64[input[i]>>2];
  76. output[j+1] = basis_64[((input[i] & 0x03) << 4) | ((input[i+1] & 0xf0) >> 4)];
  77. output[j+2] = basis_64[((input[i+1] & 0x0f) << 2) | ((input[i+2] & 0xc0) >> 6)];
  78. output[j+3] = basis_64[input[i+2] & 0x3f];
  79. }
  80. i += 3;
  81. j += 4;
  82. }
  83. return j;
  84. }
  85. /* This assumes that an unsigned char is exactly 8 bits. Not portable code! :-) */
  86. static unsigned char index_64[128] = {
  87.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  88.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  89.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,   62, 0xff, 0xff, 0xff,   63,
  90.       52,   53,   54,   55,   56,   57,   58,   59,   60,   61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  91.     0xff,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
  92.       15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25, 0xff, 0xff, 0xff, 0xff, 0xff,
  93.     0xff,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
  94.       41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51, 0xff, 0xff, 0xff, 0xff, 0xff
  95. };
  96. #define char64(c)  ((c > 127) ? 0xff : index_64[(c)])
  97. int base64decode(const unsigned char *input, int input_length, unsigned char *output, int output_length)
  98. {
  99. int i = 0, j = 0, pad;
  100. unsigned char c[4];
  101. ASSERT(output_length >= (input_length * 3 / 4));
  102. ASSERT((input_length % 4) == 0);
  103. while ((i + 3) < input_length) {
  104. pad  = 0;
  105. c[0] = char64(input[i  ]); pad += (c[0] == 0xff);
  106. c[1] = char64(input[i+1]); pad += (c[1] == 0xff);
  107. c[2] = char64(input[i+2]); pad += (c[2] == 0xff);
  108. c[3] = char64(input[i+3]); pad += (c[3] == 0xff);
  109. if (pad == 2) {
  110. output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  111. output[j]   = (c[1] & 0x0f) << 4;
  112. } else if (pad == 1) {
  113. output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  114. output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
  115. output[j]   = (c[2] & 0x03) << 6;
  116. } else {
  117. output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
  118. output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
  119. output[j++] = ((c[2] & 0x03) << 6) | (c[3] & 0x3f);
  120. }
  121. i += 4;
  122. }
  123. return j;
  124. }