kopia lustrzana https://github.com/jamescoxon/dl-fldigi
246 wiersze
5.3 KiB
C++
246 wiersze
5.3 KiB
C++
// ----------------------------------------------------------------------------
|
|
// Copyright (C) 2014
|
|
// David Freese, W1HKJ
|
|
//
|
|
// This file is part of fldigi
|
|
//
|
|
// fldigi is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// fldigi is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
//=====================================================================
|
|
//
|
|
// base64 encoding / decoding class
|
|
//
|
|
// To create a standalone base64 encode/coder:
|
|
// g++ -DTEST b64.cxx -o base64
|
|
//
|
|
// To use in a calling program:
|
|
//
|
|
// base64 b64; // default no CRLF's in output file
|
|
// base 64 b64(true); // insert CRLF's in output file
|
|
// pass c++ string into encoder / decoder
|
|
// return value is encoded / decoded string
|
|
// original string is left unchanged
|
|
//
|
|
// string instr, outstr;
|
|
// outstr = b64.encoder(instr);
|
|
// outstr = b64.decoder(instr);
|
|
//=====================================================================
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include "b64.h"
|
|
|
|
void base64::init()
|
|
{
|
|
iolen = 0;
|
|
iocp = 0;
|
|
ateof = false;
|
|
linelength = 0;
|
|
|
|
// create the etable for encoding
|
|
for (int i = 0; i < 9; i++) {
|
|
etable[i] = 'A' + i;
|
|
etable[i + 9] = 'J' + i;
|
|
etable[26 + i] = 'a' + i;
|
|
etable[26 + i + 9] = 'j' + i;
|
|
}
|
|
for (int i = 0; i < 8; i++) {
|
|
etable[i + 18] = 'S' + i;
|
|
etable[26 + i + 18] = 's' + i;
|
|
}
|
|
for (int i = 0; i < 10; i++)
|
|
etable[52 + i] = '0' + i;
|
|
etable[62] = '+';
|
|
etable[63] = '/';
|
|
|
|
// create the dtable for decoding
|
|
for (int i= 0; i < 255; i++)
|
|
dtable[i] = 0x80;
|
|
for (int i = 'A'; i <= 'I'; i++)
|
|
dtable[i] = 0 + (i - 'A');
|
|
for (int i = 'J'; i <= 'R'; i++)
|
|
dtable[i] = 9 + (i - 'J');
|
|
for (int i = 'S'; i <= 'Z'; i++)
|
|
dtable[i] = 18 + (i - 'S');
|
|
for (int i = 'a'; i <= 'i'; i++)
|
|
dtable[i] = 26 + (i - 'a');
|
|
for (int i = 'j'; i <= 'r'; i++)
|
|
dtable[i] = 35 + (i - 'j');
|
|
for (int i = 's'; i <= 'z'; i++)
|
|
dtable[i] = 44 + (i - 's');
|
|
for (int i = '0'; i <= '9'; i++)
|
|
dtable[i] = 52 + (i - '0');
|
|
dtable[(int)'+'] = 62;
|
|
dtable[(int)'/'] = 63;
|
|
dtable[(int)'='] = 0;
|
|
}
|
|
|
|
string base64::encode(string in)
|
|
{
|
|
int n;
|
|
byte igroup[3], ogroup[4];
|
|
|
|
output = "";
|
|
iocp = 0;
|
|
ateof = false;
|
|
if (crlf)
|
|
linelength = 0;
|
|
iolen = in.length();
|
|
|
|
while (!ateof) {
|
|
igroup[0] = igroup[1] = igroup[2] = 0;
|
|
for (n = 0; n < 3; n++) {
|
|
if (iocp == iolen) {
|
|
ateof = true;
|
|
break;
|
|
}
|
|
igroup[n] = (byte)in[iocp];
|
|
iocp++;
|
|
}
|
|
if (n > 0) {
|
|
ogroup[0] = etable[igroup[0] >> 2];
|
|
ogroup[1] = etable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
|
|
ogroup[2] = etable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
|
|
ogroup[3] = etable[igroup[2] & 0x3F];
|
|
if (n < 2) {
|
|
ogroup[2] = '=';
|
|
if (n < 1) {
|
|
ogroup[2] = '=';
|
|
}
|
|
}
|
|
for (int i = 0; i < 4; i++) {
|
|
if (crlf)
|
|
if (linelength >= LINELEN) {
|
|
// output += '\r';
|
|
output += '\n';
|
|
linelength = 0;
|
|
}
|
|
output += (byte)ogroup[i];
|
|
if (crlf)
|
|
linelength++;
|
|
}
|
|
}
|
|
}
|
|
if (crlf) {
|
|
// output += '\r';
|
|
output += '\n';
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
string base64::decode(string in)
|
|
{
|
|
int i;
|
|
output = "";
|
|
iocp = 0;
|
|
iolen = in.length();
|
|
byte c;
|
|
|
|
while (iocp < iolen) {
|
|
byte a[4], b[4], o[3];
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (iocp == iolen) {
|
|
output = "b64 file length error.\n";
|
|
return output;
|
|
}
|
|
c = in[iocp++];
|
|
while (c <= ' ') {
|
|
if (iocp == iolen) {
|
|
return output;
|
|
}
|
|
c = in[iocp++];
|
|
}
|
|
if (dtable[c] & 0x80) {
|
|
output = "Illegal character in b64 file.\n";
|
|
return output;
|
|
}
|
|
a[i] = c;
|
|
b[i] = (byte)dtable[c];
|
|
}
|
|
o[0] = (b[0] << 2) | (b[1] >> 4);
|
|
o[1] = (b[1] << 4) | (b[2] >> 2);
|
|
o[2] = (b[2] << 6) | b[3];
|
|
output += o[0];
|
|
if (a[2] != '=') {
|
|
output += o[1];
|
|
if (a[3] != '=')
|
|
output += o[2];
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
|
|
#ifdef TEST
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
|
|
void usage(void)
|
|
{
|
|
printf("b64 -- Encode/decode file as base64. Call:\n");
|
|
printf(" b64 e/d < infile > outfile\n");
|
|
}
|
|
|
|
int main(int argc,char*argv[])
|
|
{
|
|
char opt;
|
|
bool decoding = false;
|
|
char * cp;
|
|
byte c;
|
|
|
|
string inputstring;
|
|
string infilename;
|
|
string outputstring;
|
|
string outfilename;
|
|
|
|
base64 b64;
|
|
|
|
if (argc < 2) {
|
|
usage();
|
|
return(0);
|
|
}
|
|
opt = *(argv[1]);
|
|
|
|
if (opt == 'd' || opt == 'D') {
|
|
while (!std::cin.eof()) {
|
|
c = std::cin.get();
|
|
if (!std::cin.eof())
|
|
inputstring += c;
|
|
}
|
|
outputstring = b64.decode( inputstring );
|
|
size_t len = outputstring.length();
|
|
for (size_t n = 0; n < len; n++)
|
|
std::cout << (unsigned char)outputstring[n];
|
|
} else if (opt == 'e' || opt == 'E') {
|
|
while (!std::cin.eof()) {
|
|
c = std::cin.get();
|
|
if (!std::cin.eof())
|
|
inputstring += c;
|
|
}
|
|
outputstring = b64.encode( inputstring );
|
|
size_t len = outputstring.length();
|
|
for (size_t n = 0; n < len; n++)
|
|
std::cout << (unsigned char)outputstring[n];
|
|
} else
|
|
usage();
|
|
|
|
return 0;
|
|
}
|
|
#endif
|