上代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h> const char padding = '=';
const char base64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const char base64d[] = {
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f,
0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0xff,0xff,0xff,0x00,0xff,0xff,
0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff,
0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33}; /*
根据 base64e 得到 base64d
base64d 的长度为 base64e 和 padding 字符ascii码最大值
*/
void get_base64d(void) {
if (strlen(base64e) != 64) {
printf("encoding alphabet is not 64-bytes long\n");
exit(1); // 必须是64个字符
}
int i, j;
for (i=0;i<64;i++) {
if (base64e[i] == '\n' || base64e[i] == '\r') {
printf("encoding alphabet contains newline character\n");
exit(1); // 不能包含换行回车字符
}
if (base64e[i] == padding) {
printf("there are duplicate characters :%c\n", base64e[i]);
exit(1); // 不能和padding相同
}
for (j=i+1;j<64;j++) {
if (base64e[i] == base64e[j]) {
printf("there are duplicate characters :%c\n", base64e[i]);
exit(1); // 不能存在2个相同字符
}
}
} char tmp[256]; // 预设256个字符,并初始化
for (i=0; i<256;i++){
tmp[i] = 0xff;
}
for (i = 0,j = -1; base64e[i] != 0 ;i++) {
tmp[base64e[i]] = i; // 将对应位置置为ascii码值
if (base64e[i] > j) {
j = base64e[i]; // 找到ascii码最大值
}
}
tmp[padding] = 0;
if (padding > j) {
j = padding; // padding也要计入最大值里面
} // 打印得到的数组,不必为256那么长,只要包含最大ascii值就行
printf("const char base64d[] = {");
for (i=0; i <= j ;i++) {
if (((i+1)%16) == 1)
printf("\n");
printf("0x%02x,", tmp[i]&0xff);
}
printf("\b};\n");
} // max_len为dest最大长度,可能存在编码不全,需要保证max_len够长
void encode_base_64(const char *src, char *dest, int max_len) {
int n, i;
size_t l = strlen(src);
max_len = (max_len - 1) / 4;
for(i = 0;i < max_len && l >= 3; i++, src += 3, l -= 3) {
n = src[0] << 16 | src[1] << 8 | src[2];
*dest++ = base64e[(n >> 18) & 0x3f];
*dest++ = base64e[(n >> 12) & 0x3f];
*dest++ = base64e[(n >> 6) & 0x3f];
*dest++ = base64e[n & 0x3f];
}
if (l == 1) {
n = src[0] << 16;
*dest++ = base64e[(n >> 18) & 0x3f];
*dest++ = base64e[(n >> 12) & 0x3f];
*dest++ = padding;
*dest++ = padding;
} else if (l == 2) {
n = src[0] << 16 | src[1] << 8;
*dest++ = base64e[(n >> 18) & 0x3f];
*dest++ = base64e[(n >> 12) & 0x3f];
*dest++ = base64e[(n >> 6) & 0x3f];
*dest++ = padding;
}
*dest = 0;
} // max_len为dest最大长度,可能解码不全,需要保证max_len够长
// 如果真的不够用那只能存max_len-1个字符,最后一位为'\0'结束符
void decode_base_64(const char *src,char *dest, int max_len) {
size_t l = strlen(src);
int n, i;
for (i=0; i<l; i+=4) {
n = base64d[src[i]]<<18 | base64d[src[i+1]]<<12 |
base64d[src[i+2]]<<6 | base64d[src[i+3]]; if (--max_len <= 0) break;
*dest++ = (n>>16)&0xff;
if (--max_len <= 0) break;
*dest++ = (n>>8)&0xff;
if (--max_len <= 0) break;
*dest++ = n&0xff;
}
*dest = 0;
} int main(int argc,char *argv[])
{
if (argc != 2) {
printf("usage :%s [get|string]\n", argv[0]);
return 0;
}
if (strcmp(argv[1],"get") == 0) {
get_base64d();
return 0;
} int len = strlen(argv[1])*2; // 预留足够的存储空间
char *s1 = (char*)malloc(sizeof(char)*len);
if (NULL == s1) {
printf("malloc error\n");
return 1;
}
char *s2 = (char*)malloc(sizeof(char)*len);
if (NULL == s2) {
printf("malloc error\n");
return 1;
}
strcpy(s1, argv[1]);
printf("baseStr:\"%s\"\n", s1); encode_base_64(s1,s2,len);
printf("base64e:\"%s\"\n", s2); decode_base_64(s2,s1,len);
printf("base64d:\"%s\"\n", s1);
return 0;
}

执行.\a.exe get 会执行get_base64d根据base64e和padding产生一个base64d用于解码时候查表,这样解码更快速。下面放一个执行结果:

.\a.exe asdzxcaqwe
baseStr:"asdzxcaqwe"
base64e:"YXNkenhjYXF3ZQ=="
base64d:"asdzxcaqwe"

实现base64的编码解码,深刻理解base64的更多相关文章

  1. C#中Base64之编码,解码方法

    原文:C#中Base64之编码,解码方法 1.base64  to  string string strPath =  "aHR0cDovLzIwMy44MS4yOS40Njo1NTU3L1 ...

  2. python 对任意文件(jpg,png,mp3,mp4)base64的编码解码

    程序是事件驱动的,写博客是什么驱动的?事件? 时间?no,我承认我很懒,甚至不愿意记录总结.哪是什么驱动的? 对! 问题驱动的.遇到了问题解决了问题突然想起来搬到blog上,让遇到相同问题的可以参考下 ...

  3. base64的编码解码的一些坑

    1. //编码 value = base64encode(utf16to8(src)) //解码 value = utf8to16(base64decode(src)) 这里:base64编码之前先转 ...

  4. C++ Base64 编码 解码

    C++实现 base64 字符串编码解码(GCC编译). /** * @brief C++ base64 编解码 * @author wid * @date 2013-20-25 * * @note ...

  5. 理解netty对protocol buffers的编码解码

    一,netty+protocol buffers简要说明 Netty是业界最流行的NIO框架之一优点:1)API使用简单,开发门槛低:2)功能强大,预置了多种编解码功能,支持多种主流协议:3)定制能力 ...

  6. 从原理上理解Base64编码

    开发者对Base64编码肯定很熟悉,是否对它有很清晰的认识就不一定了.实际 上Base64已经简单到不能再简单了,如果对它的理解还是模棱两可实在不应该.大概介绍一下Base64的相关内容,花几分钟时间 ...

  7. 《PHP 实现 Base64 编码/解码》笔记

    前言 早在去年 11 月底就已经看过<PHP 实现 Base64 编码/解码>这篇文章了,由于当时所掌握的位运算知识过于薄弱,所以就算是看过几遍也是囫囵吞枣一般,不出几日便忘记了其滋味. ...

  8. URI编码解码和base64

    概述 对于uri的编解码,在js中有3对函数,分别是escape/unescape,encodeURI/decodeURI,encodeURIComponent/decodeURIComponent. ...

  9. c# base64 编码解码

    一. Base64的编码规则 Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编 码.它将需要编码的数据拆分成字节数组.以3个字节为一组.按顺序排列24 位数据,再把这24位数 ...

随机推荐

  1. h5内嵌微信小程序,调用微信支付功能

    在小程序中不能使用之前在浏览器中配置的支付功能,只能调用小程序专属的api进行支付. 因为需要在现在实现的基础上,再添加在小程序中调用微信支付功能,所以我的思路是这样的 1.在点击支付按钮时,判断是不 ...

  2. Kubernetes 服务部署最佳实践(二) ——如何提高服务可用性

    引言 上一篇文章我们围绕如何合理利用资源的主题做了一些最佳实践的分享,这一次我们就如何提高服务可用性的主题来展开探讨. 怎样提高我们部署服务的可用性呢?K8S 设计本身就考虑到了各种故障的可能性,并提 ...

  3. python连接websocket wss

    def websocket_wss(): try: wss = create_connection(wss_url, timeout=10) if wss.status == 101: wss.sen ...

  4. centos7使用Minikube“快速搭建“出Kubernetes本地实验环境(踩坑集锦及解决方案)

    先决条件(先假设你做完这两步骤) 检查Linux是否支持虚拟化,验证输出是否为非空如何开启虚拟化 grep -E --color 'vmx|svm' /proc/cpuinfo 安装 kubectl ...

  5. oracle之二表的几种类型

    Oracle中表的几种类型 1.表的功能:存储.管理数据的基本单元(二维表:有行和列组成)2.表的类型: 1)堆表:heap table :数据存储时,行是无序的,对它的访问采用全表扫描. 2)分区表 ...

  6. 3.CDN加速简介

    什么是CDN CDN的全称是Content Delivery Network,即内容分发网络.CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问 ...

  7. 对比ERP解读企业资产管理EAM在电力行业应用

    对比ERP解读企业资产管理EAM在电力行业应用 .关于EAMEAM (Enterprise Asset Management)企业资产管理,是面向固定资产占企业资产主要部分的资产密集型(Capital ...

  8. 自己实现一个 DFA 串模式识别器(二)

    正规表达式的实现原理 ​ 上文讨论了串的模式的表达,即正规表达式.那么这一小节将讨论我们实现一个正规表达式的方法和原理.因为我们知道,一个正规表达式对应着一个串模式,而一个串模式又对应着一些列符合该模 ...

  9. 解决vue版本不匹配的问题 Vue packages version mismatch:

    解决方式:重新单独安装提示冲突的模块  比如如上的冲突,我重新下载了 npm i vue-template-compiler@2.6.7 --save 再重新启动就可以了 npm run dev

  10. Redis中的订阅模式

    redis中的客户端可以订阅一个自定义的频道,接受来自该频道的消息 订阅 订阅指定频道-SUBSCRIBE SUBSCRIBE channel [channel2]... SUBSCRIBE 频道名 ...