File: base64.cpp

package info (click to toggle)
rdkit 201809.1%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 123,688 kB
  • sloc: cpp: 230,509; python: 70,501; java: 6,329; ansic: 5,427; sql: 1,899; yacc: 1,739; lex: 1,243; makefile: 445; xml: 229; fortran: 183; sh: 123; cs: 93
file content (136 lines) | stat: -rw-r--r-- 4,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// $Id$
//
// Copyright (c) 2002-2008 greg landrum and rational discovery llc
//
//  @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#include <iostream>
#include <cstring>
#include "base64.h"
// Encoding table from RFC 2045
//
//     Value Encoding  Value Encoding  Value Encoding  Value Encoding
//         0 A            17 R            34 i            51 z
//         1 B            18 S            35 j            52 0
//         2 C            19 T            36 k            53 1
//         3 D            20 U            37 l            54 2
//         4 E            21 V            38 m            55 3
//         5 F            22 W            39 n            56 4
//         6 G            23 X            40 o            57 5
//         7 H            24 Y            41 p            58 6
//         8 I            25 Z            42 q            59 7
//         9 J            26 a            43 r            60 8
//        10 K            27 b            44 s            61 9
//        11 L            28 c            45 t            62 +
//        12 M            29 d            46 u            63 /
//        13 N            30 e            47 v
//        14 O            31 f            48 w         (pad) =
//        15 P            32 g            49 x
//        16 Q            33 h            50 y

char *Base64Encode(const char *inText, const unsigned int inLen) {
  return Base64Encode((const unsigned char *)inText, inLen);
}

char *Base64Encode(const unsigned char *inText, const unsigned int inLen) {
  // Notes:
  //   - whoever calls us is responsible for free'ing the result we return
  //   - we cheat and don't worry about breaking lines
  static unsigned char transTable[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', '+', '/'};

  char *res;
  int resSize;
  resSize = (4 * inLen) / 3;
  while (resSize % 4) resSize++;
  res = new char[resSize + 1];
  unsigned int i = 0;
  int pos = 0;
  while (i < inLen) {
    res[pos++] = transTable[inText[i] >> 2];
    if (i + 1 < inLen) {
      res[pos++] = transTable[((inText[i] & 3) << 4) | (inText[i + 1] >> 4)];
      if (i + 2 < inLen) {
        res[pos++] =
            transTable[((inText[i + 1] & 0xF) << 2) | (inText[i + 2] >> 6)];
        res[pos++] = transTable[inText[i + 2] & 0x3F];
      } else {
        // single padding
        res[pos++] = transTable[((inText[i + 1] & 0xF) << 2)];
        res[pos++] = '=';
      }
    } else {
      // double padding
      res[pos++] = transTable[((inText[i] & 3) << 4)];
      res[pos++] = '=';
      res[pos++] = '=';
    }
    i += 3;
  }
  res[resSize] = 0;
  return res;
}

char *Base64Decode(const char *inText, unsigned int *size) {
  // Notes:
  //   - whoever calls us is responsible for free'ing the result we return

  unsigned char transTable[256];
  size_t inLen = strlen(inText);

  size_t i;
  // FIX: we don't really need to build this table here
  for (i = 0; i < 255; i++) {
    transTable[i] = 0x80;
  }
  for (i = 'A'; i <= 'Z'; i++) transTable[i] = (unsigned char)i - 'A';
  for (i = 'a'; i <= 'z'; i++) transTable[i] = (unsigned char)i - 'a' + 26;
  for (i = '0'; i <= '9'; i++) transTable[i] = (unsigned char)i - '0' + 52;
  transTable[static_cast<int>('+')] = 62;
  transTable[static_cast<int>('/')] = 63;

  size_t outLen = 3 * inLen / 4;
  auto *res = new char[outLen];
  res[outLen - 1] = 0;
  size_t pos = 0;
  i = 0;
  // decode 4 bytes at a time
  unsigned char block[4];
  int nInBlock = 0;
  while (i < inLen) {
    unsigned char c = inText[i];

    // above we set 0x80 as the junk marker in the translation table
    if (!(transTable[c] & 0x80)) {
      block[nInBlock++] = transTable[c];
      if (nInBlock == 4) {
        // finished a block
        res[pos++] = (block[0] << 2) | (block[1] >> 4);
        res[pos++] = (block[1] << 4) | (block[2] >> 2);
        res[pos++] = (block[2] << 6) | block[3];
        nInBlock = 0;
      }
    }
    i++;
  }

  // okay, now there can be 2 or 3 chars remaining to be processed
  //  (before the padding)
  if (nInBlock > 1) {
    res[pos++] = (block[0] << 2) | (block[1] >> 4);
    if (nInBlock > 2) {
      res[pos++] = (block[1] << 4) | (block[2] >> 2);
      res[pos] = (block[2] << 6);
    }
  }
  *size = pos;
  return res;
}