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;
}
|