mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
141 lines
4.6 KiB
C++
141 lines
4.6 KiB
C++
// $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
|
|
|
|
//const int MaxLineLength=72;
|
|
|
|
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];
|
|
int inLen = strlen(inText);
|
|
|
|
int 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;
|
|
|
|
int outLen = 3*inLen/4;
|
|
char *res = new char[outLen];
|
|
res[outLen-1]=0;
|
|
int 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;
|
|
}
|