Add base64 encoder/decoder
This commit is contained in:
parent
70cae879e3
commit
a596c525ad
3 changed files with 66 additions and 8 deletions
|
@ -1208,4 +1208,63 @@ string filterANSIEscapes(const string & s, bool nixOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
|
string base64Encode(const string & s)
|
||||||
|
{
|
||||||
|
string res;
|
||||||
|
int data = 0, nbits = 0;
|
||||||
|
|
||||||
|
for (char c : s) {
|
||||||
|
data = data << 8 | (unsigned char) c;
|
||||||
|
nbits += 8;
|
||||||
|
while (nbits >= 6) {
|
||||||
|
nbits -= 6;
|
||||||
|
res.push_back(base64Chars[data >> nbits & 0x3f]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbits) res.push_back(base64Chars[data << (6 - nbits) & 0x3f]);
|
||||||
|
while (res.size() % 4) res.push_back('=');
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string base64Decode(const string & s)
|
||||||
|
{
|
||||||
|
bool init = false;
|
||||||
|
char decode[256];
|
||||||
|
if (!init) {
|
||||||
|
// FIXME: not thread-safe.
|
||||||
|
memset(decode, -1, sizeof(decode));
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
decode[(int) base64Chars[i]] = i;
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string res;
|
||||||
|
unsigned int d = 0, bits = 0;
|
||||||
|
|
||||||
|
for (char c : s) {
|
||||||
|
if (c == '=') break;
|
||||||
|
if (c == '\n') continue;
|
||||||
|
|
||||||
|
char digit = decode[(unsigned char) c];
|
||||||
|
if (digit == -1)
|
||||||
|
throw Error("invalid character in Base64 string");
|
||||||
|
|
||||||
|
bits += 6;
|
||||||
|
d = d << 6 | digit;
|
||||||
|
if (bits >= 8) {
|
||||||
|
res.push_back(d >> (bits - 8) & 0xff);
|
||||||
|
bits -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,4 +398,9 @@ void ignoreException();
|
||||||
string filterANSIEscapes(const string & s, bool nixOnly = false);
|
string filterANSIEscapes(const string & s, bool nixOnly = false);
|
||||||
|
|
||||||
|
|
||||||
|
/* Base64 encoding/decoding. */
|
||||||
|
string base64Encode(const string & s);
|
||||||
|
string base64Decode(const string & s);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1023,14 +1023,8 @@ static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
|
||||||
if (crypto_sign_keypair(pk, sk) != 0)
|
if (crypto_sign_keypair(pk, sk) != 0)
|
||||||
throw Error("key generation failed");
|
throw Error("key generation failed");
|
||||||
|
|
||||||
// FIXME: super ugly way to do base64 encoding.
|
std::cout << keyName << ":" << base64Encode(string((char *) pk, crypto_sign_PUBLICKEYBYTES)) << std::endl;
|
||||||
auto args = Strings({"-MMIME::Base64", "-0777", "-ne", "print encode_base64($_, '')"});
|
std::cout << keyName << ":" << base64Encode(string((char *) sk, crypto_sign_SECRETKEYBYTES)) << std::endl;
|
||||||
|
|
||||||
string pk64 = runProgram("perl", true, args, string((char *) pk, crypto_sign_PUBLICKEYBYTES));
|
|
||||||
std::cout << keyName << ":" << pk64 << std::endl;
|
|
||||||
|
|
||||||
string sk64 = runProgram("perl", true, args, string((char *) sk, crypto_sign_SECRETKEYBYTES));
|
|
||||||
std::cout << keyName << ":" << sk64 << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue