116 lines
3.2 KiB
C++
116 lines
3.2 KiB
C++
/*
|
|
* Copyright (C) 2006-2016 Jacek Sieka, arnetheduck on gmail point com
|
|
*
|
|
* This program 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 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "adchpp.h"
|
|
|
|
#include "Encoder.h"
|
|
#include "common.h"
|
|
|
|
namespace adchpp {
|
|
|
|
using namespace std;
|
|
|
|
const int8_t Encoder::base32Table[256] = {
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,26,27,28,29,30,31,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1, 0, 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,-1,-1,-1,-1,-1,
|
|
-1, 0, 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,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
};
|
|
|
|
const char Encoder::base32Alphabet[32] = {
|
|
'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', '2', '3', '4', '5', '6', '7'
|
|
};
|
|
|
|
string& Encoder::toBase32(const uint8_t* src, size_t len, string& dst) {
|
|
// Code snagged from the bitzi bitcollider
|
|
size_t i, index;
|
|
uint8_t word;
|
|
dst.reserve(((len * 8) / 5) + 1);
|
|
|
|
for(i = 0, index = 0; i < len;) {
|
|
/* Is the current word going to span a byte boundary? */
|
|
if (index > 3) {
|
|
word = (uint8_t)(src[i] & (0xFF >> index));
|
|
index = (index + 5) % 8;
|
|
word <<= index;
|
|
if ((i + 1) < len)
|
|
word |= src[i + 1] >> (8 - index);
|
|
|
|
i++;
|
|
} else {
|
|
word = (uint8_t)(src[i] >> (8 - (index + 5))) & 0x1F;
|
|
index = (index + 5) % 8;
|
|
if (index == 0)
|
|
i++;
|
|
}
|
|
|
|
dcassert(word < 32);
|
|
dst += base32Alphabet[word];
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
void Encoder::fromBase32(const char* src, uint8_t* dst, size_t len) {
|
|
size_t i, index, offset;
|
|
|
|
memset(dst, 0, len);
|
|
for(i = 0, index = 0, offset = 0; src[i]; i++) {
|
|
// Skip what we don't recognise
|
|
int8_t tmp = base32Table[(unsigned char)src[i]];
|
|
|
|
if(tmp == -1)
|
|
continue;
|
|
|
|
if (index <= 3) {
|
|
index = (index + 5) % 8;
|
|
if (index == 0) {
|
|
dst[offset] |= tmp;
|
|
offset++;
|
|
if(offset == len)
|
|
break;
|
|
} else {
|
|
dst[offset] |= tmp << (8 - index);
|
|
}
|
|
} else {
|
|
index = (index + 5) % 8;
|
|
dst[offset] |= (tmp >> index);
|
|
offset++;
|
|
if(offset == len)
|
|
break;
|
|
dst[offset] |= tmp << (8 - index);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|