当前位置: 首页 > news >正文

c++ Base58编码解码

Base58

  • 字符集 Base58 使用 58 个字符进行编码,字符集为:123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz。注意:0(零)、O(大写字母O)、I(大写字母I)和 l(小写字母L)等字符被排除,以避免视觉上的混淆。

  • 编码长度:Base58 编码和 Base64 类似,但由于字符集更小,编码后的长度比 Base64 稍短。

  • 应用场景

  • 主要用于加密货币(如比特币)中,作为钱包地址等信息的编码方式。

  • 由于字符集避免了视觉上容易混淆的字符,因此在用户界面中显示时更为友好。

  • 示例

"Hello" -> "JxF12TrwUP45p7r"
#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;/** All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
static const int8_t mapBase58[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, 0, 1, 2, 3, 4, 5, 6,  7, 8,-1,-1,-1,-1,-1,-1,-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,47,48,49,50,51,52,53,54, 55,56,57,-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,
};
constexpr inline bool IsSpace(char c) noexcept {return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
}bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_len)
{// Skip leading spaces.while (*psz && IsSpace(*psz))psz++;// Skip and count leading '1's.int zeroes = 0;int length = 0;while (*psz == '1') {zeroes++;if (zeroes > max_ret_len) return false;psz++;}// Allocate enough space in big-endian base256 representation.int size = strlen(psz) * 733 / 1000 + 1; // log(58) / log(256), rounded up.std::vector<unsigned char> b256(size);// Process the characters.static_assert(sizeof(mapBase58) / sizeof(mapBase58[0]) == 256, "mapBase58.size() should be 256"); // guarantee not out of rangewhile (*psz && !IsSpace(*psz)) {// Decode base58 characterint carry = mapBase58[(uint8_t)*psz];if (carry == -1)  // Invalid b58 characterreturn false;int i = 0;for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {carry += 58 * (*it);*it = carry % 256;carry /= 256;}assert(carry == 0);length = i;if (length + zeroes > max_ret_len) return false;psz++;}// Skip trailing spaces.while (IsSpace(*psz))psz++;if (*psz != 0)return false;// Skip leading zeroes in b256.std::vector<unsigned char>::iterator it = b256.begin() + (size - length);// Copy result into output vector.vch.reserve(zeroes + (b256.end() - it));vch.assign(zeroes, 0x00);while (it != b256.end())vch.push_back(*(it++));return true;
}std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{// Skip & count leading zeroes.int zeroes = 0;int length = 0;while (pbegin != pend && *pbegin == 0) {pbegin++;zeroes++;}// Allocate enough space in big-endian base58 representation.int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up.std::vector<unsigned char> b58(size);// Process the bytes.while (pbegin != pend) {int carry = *pbegin;int i = 0;// Apply "b58 = b58 * 256 + ch".for (auto it = b58.rbegin();(carry != 0 || i < length) && (it != b58.rend());it++, i++) {carry += 256 * (*it);*it = carry % 58;carry /= 58;}assert(carry == 0);length = i;pbegin++;}// Skip leading zeroes in base58 result.std::vector<unsigned char>::iterator it = b58.begin() + (size - length);while (it != b58.end() && *it == 0)it++;// Translate the result into a string.std::string str;str.reserve(zeroes + (b58.end() - it));str.assign(zeroes, '1');while (it != b58.end())str += pszBase58[*(it++)];return str;
}int main(int argc, char argv[])
{unsigned char data[] = "测试base58数据";int len = sizeof(data);cout << data << endl;std::string re = EncodeBase58(data, data + len);cout << re << endl;std::vector<unsigned char> vsh;DecodeBase58(re.data(), vsh, 4096);cout << vsh.data() << endl;return 0;
}

相关文章:

  • [创业之路-407]:价值、价格、供求关系的规律如何指导创业和战略选择?
  • 【JS进阶】ES6 实现继承的方式
  • ARM处理器工作模式
  • NineData云原生智能数据管理平台新功能发布|2025年5月版
  • 算法篇 八大排序(冒泡 插入 选择 堆 希尔 快排 归并 计数)
  • Pandas和Django的示例Demo
  • 使用联邦多轨迹图神经网络(GNNs)结合稀缺数据预测婴儿脑连接|文献速递-深度学习医疗AI最新文献
  • Honor of Kings 2025.06.05
  • 【无标题】路径着色问题的革命性重构:拓扑色动力学模型下的超越与升华
  • Android四大组件通讯指南:Kotlin版组件茶话会
  • .net Span类型和Memory类型
  • 02 Deep learning神经网络的编程基础 逻辑回归--吴恩达
  • 实现基于Yolo的异常聚集算法
  • 任务调度器-关于中心化调度 vs 去中心化调度的核心区别
  • C++11 尾随返回类型:从入门到精通
  • 在 UE5 蓝图中配置Actor类型的Asset以作为位置和旋转设置目标
  • 【python深度学习】Day 45 Tensorboard使用介绍
  • 中国企业在泰国推广ERP(SAP、Oracle)-增值税(VAT)处理关键规则 及ERP系统配置要点
  • Spring中@Primary注解的作用与使用
  • Ruoyi多主键表的增删改查
  • 免费做代理的网站/齐三seo顾问
  • 推荐做网站的公司/无锡百度竞价推广
  • 阿里云iis放网站/汕头seo关键词排名
  • 专业格泰建站/搜索引擎优化的流程
  • 网易做网站/天津做优化好的公司
  • 网站成功案例分析/常州seo第一人