Files
lib-privatebin/src/base58.cpp

89 lines
2.5 KiB
C++

#include "base58.h"
#include <algorithm>
#include <stdexcept>
const std::string Base58::ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
std::string Base58::encode(const std::vector<unsigned char>& data) {
if (data.empty()) {
return "";
}
// Skip leading zeros
size_t leading_zeros = 0;
while (leading_zeros < data.size() && data[leading_zeros] == 0) {
leading_zeros++;
}
// Convert to base58
std::vector<unsigned char> digits((data.size() - leading_zeros) * 138 / 100 + 1);
size_t digitslen = 1;
for (size_t i = leading_zeros; i < data.size(); i++) {
unsigned int carry = data[i];
for (size_t j = 0; j < digitslen; j++) {
carry += (unsigned int)(digits[j]) << 8;
digits[j] = carry % 58;
carry /= 58;
}
while (carry > 0) {
digits[digitslen++] = carry % 58;
carry /= 58;
}
}
// Convert to string
std::string result;
for (size_t i = 0; i < leading_zeros; i++) {
result += ALPHABET[0];
}
for (size_t i = 0; i < digitslen; i++) {
result += ALPHABET[digits[digitslen - 1 - i]];
}
return result;
}
std::vector<unsigned char> Base58::decode(const std::string& encoded) {
if (encoded.empty()) {
return std::vector<unsigned char>();
}
// Skip leading '1's (which represent leading zeros)
size_t leading_ones = 0;
while (leading_ones < encoded.length() && encoded[leading_ones] == '1') {
leading_ones++;
}
// Convert from base58
std::vector<unsigned char> bytes((encoded.length() - leading_ones) * 733 / 1000 + 1);
size_t byteslen = 1;
for (size_t i = leading_ones; i < encoded.length(); i++) {
unsigned int carry = ALPHABET.find(encoded[i]);
if (carry == std::string::npos) {
throw std::invalid_argument("Invalid character in Base58 string");
}
for (size_t j = 0; j < byteslen; j++) {
carry += (unsigned int)(bytes[j]) * 58;
bytes[j] = carry & 0xff;
carry >>= 8;
}
while (carry > 0) {
bytes[byteslen++] = carry & 0xff;
carry >>= 8;
}
}
// Add leading zeros
std::vector<unsigned char> result(leading_ones + byteslen);
for (size_t i = 0; i < leading_ones; i++) {
result[i] = 0;
}
for (size_t i = 0; i < byteslen; i++) {
result[leading_ones + i] = bytes[byteslen - 1 - i];
}
return result;
}