原由

项目中经常需要使用base64进行处理,通过base64可以将特殊字符转化为普通可见字符,便于网络传输,代价是增长了传输长度。

base64将每3个byte转化为4个6bit位,然后高位补两个零。这意味着,base64编码后长度会变长。

  1. 当源文长度不是3的倍数时,需要补零。编码后以等号“=”表示。至多有1至2个补零的情况出现,则结尾最多一至两个等号。
  2. 编码后长度可预测4*(len+2)/3。
  3. base64是个可逆编码。
  4. 源文长度预估如下:末尾等号个数为p(此时p小于等于2),编码长度l (此时l为4的倍数),则源文长度 ( l * 3/4 - p)
源文 源长度 base编码后 编码后长度
abc 3 YWJj 4
abca 4 YWJjYQ== 8
abcab 5 YWJjYWI= 8
abcabc 6 YWJjYWJj 8

源码请见:https://github.com/fpzeng/aes128

C语言实现

base64的源码其实没有几行,但是在项目代码中添加base64源码总有造轮子的嫌疑。这里使用libopenssl库。

 #include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <math.h> int Base64Encode(const char* message, char** buffer) { //Encodes a string to base64
BIO *bio, *b64;
FILE* stream;
int encodedSize = *ceil((double)strlen(message)/);
*buffer = (char *)malloc(encodedSize+); stream = fmemopen(*buffer, encodedSize+, "w");
b64 = BIO_new(BIO_f_base64());
bio = BIO_new_fp(stream, BIO_NOCLOSE);
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
BIO_write(bio, message, strlen(message));
BIO_flush(bio);
BIO_free_all(bio);
fclose(stream); return (); //success
}
int calcDecodeLength(const char* b64input) { //Calculates the length of a decoded base64 string
int len = strlen(b64input);
int padding = ; if (b64input[len-] == '=' && b64input[len-] == '=') //last two chars are =
padding = ;
else if (b64input[len-] == '=') //last char is =
padding = ; return (int)len*0.75 - padding;
} int Base64Decode(char* b64message, char** buffer) { //Decodes a base64 encoded string
BIO *bio, *b64;
int decodeLen = calcDecodeLength(b64message),
len = ;
*buffer = (char*)malloc(decodeLen+);
FILE* stream = fmemopen(b64message, strlen(b64message), "r"); b64 = BIO_new(BIO_f_base64());
bio = BIO_new_fp(stream, BIO_NOCLOSE);
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
len = BIO_read(bio, *buffer, strlen(b64message));
//Can test here if len == decodeLen - if not, then return an error
(*buffer)[len] = '\0'; BIO_free_all(bio);
fclose(stream); return (); //success
} int main() {
//Encode To Base64
char* base64EncodeOutput;
char* pPlainText = "Hi, I'm fpzeng";
printf("Input plain text: %s\n", pPlainText);
Base64Encode(pPlainText, &base64EncodeOutput);
printf("Output (base64): %s\n", base64EncodeOutput); //Decode From Base64
char* base64DecodeOutput;
Base64Decode(base64EncodeOutput, &base64DecodeOutput);
printf("Output: %s\n", base64DecodeOutput); return();
}

Makefile

.PHONY : clean
OPT=-O0
DEBUG= -g
CFLAGS=-Wall -fPIC $(XCFLAGS) $(INC) $(OPT) $(SO_DEF) $(DEBUG) $(DEF)
INCLUDES = -I./
SRCS = base64.c
OBJS = $(SRCS:.c=.o)
LIBS = -lssl -lcrypto -lm MAIN = base64
all: $(MAIN)
@echo $(MAIN) has been compiled $(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
@echo output: $(OBJS)
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
clean:
@echo clean $(MAIN) $(OBJS)
rm -fr $(MAIN) $(OBJS)

  

Python实现

BASE64的实现的更多相关文章

  1. URL安全的Base64编码

    Base64编码可用于在HTTP环境下传递较长的标识信息.在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式.此时,采用Base64编码不仅比较简短,同时也具有不可 ...

  2. Base64编码

    Base64编码 写在前面 今天在做一个Android app时遇到了一个问题:Android端采用ASE对称加密的数据在JavaWeb(jre1.8.0_7)后台解密时,居然解密失败了!经过测试后发 ...

  3. Android数据加密之Base64编码算法

    前言: 前面学习总结了平时开发中遇见的各种数据加密方式,最终都会对加密后的二进制数据进行Base64编码,起到一种二次加密的效果,其实呢Base64从严格意义上来说的话不是一种加密算法,而是一种编码算 ...

  4. java单向加密算法小结(1)--Base64算法

    从这一篇起整理一下常见的加密算法以及在java中使用的demo,首先从最简单的开始. 简单了解 Base64严格来说并不是一种加密算法,而是一种编码/解码的实现方式. 我们都知道,数据在计算机网络之间 ...

  5. URI编码解码和base64

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

  6. 通过HTML5的Drag and Drop生成拓扑图片Base64信息

    HTML5 原生的 Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过 ...

  7. Base-64 字符数组或字符串的长度无效等问题解决方案

    项目特殊需要,调用ActiveX三维控件进行控件某一特殊部位的截图操作,这个截图保存由ActiveX控件控制保存到本地是没问题的,现在需要将这个截图上传到服务器,多人共享,就牵扯到需要读取本地文件…… ...

  8. android Base64 加密

    一 Base64加密 import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStre ...

  9. When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)

    关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...

  10. 网络安全——Base64编码、MD5、SHA1-SHA512、HMAC(SHA1-SHA512)哈希

    据说今天520是个好日子,为什么我想起的是502.500.404这些?还好服务器没事! 一.Base64编码 Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之 ...

随机推荐

  1. shell脚本实例一,移动文件夹中大于2000B的文件到另一个文件夹

    shell脚本能帮我们简化linux下的一些工作,现在有个需求,把TMPA文件夹下大于2000B的文件都移动到TMPB下 #! /bin/bash function movefiles() { ` d ...

  2. rownum的使用

    Oracle 提供了rownum,rownum是一个隐含的字段,默认从1开始. 取得前5条记录: 采用rownum进行分页查询: 需要使用三层嵌套查询来完成分页查询: 例如查询第三到第四条记录: se ...

  3. Android 解析JSON数组

    1:服务端是使用PHP,从数据库中查询出一个二维数组,然后调用系统函数以json格式返回给客户端. 返回结果如下:http://192.168.0.116/server/selectTitle2jso ...

  4. AltiumDesigner14板框定义及3D显示图文教程

    很多人都跟我反应说AD14不能定义板框大小,或者说是不知道怎么定义板框的大小,确实AD14的操作和AD13或者是AD10的版本斗有一些差异,尤其是现在最新的版本AltiumDesigner14.3.1 ...

  5. Qt中 QString 和int, char等的“相互”转换,关键是QString.toLocal8Bit().data();

    Qt中 int ,float ,double转换为QString 有两种方法 1.使用 QString::number(); 如: long a = 63; QString s = QString:: ...

  6. win8 开启administrator 管理员帐户

    进入命令提示符以后,输入命令:[net user administrator /active:yes]然后注销,就可以使用administrator登录.. 如果想要取消administrator激活 ...

  7. Visual Studio新建的源文件的默认编码

    原来VS新建的源文件默认的编码是根据系统locale选择的.我的是国标2312.我草.可坑死我了.一直不知道. 当时主要是需要用doxygen生成html文档,它默认的输入文件的格式是UTF-8,是不 ...

  8. 组播报文转发过程RPF

    单播报文的转发过程中,路由器并不关心组播源地址,只关心报文中的目的地址,通过目的地址决定向哪个接口转发.在组播中,报文是发送给一组接收者的,这些接收者用一个逻辑地址标识.路由器在接收到报文后,必须根据 ...

  9. 对Ul下的li标签执行点击事件——如何获取你所点击的标签

    问题所来:做项目时,一般的数据都是用循环动态加载出来的,结构都是一样的,只是绑定的值不同,如何对相同的标签做处理的问题就来了. 例如:点谁就显示谁的数值 <ul > <li id=& ...

  10. MVC实现类似QQ的网页聊天功能-ajax(下)

    此篇文章主要是对MVC实现类似QQ的网页聊天功能(上)的部分代码的解释. 首先说一下显示框的滚动条置底的问题: 结构很简单一个大的div(高度一定.overflow:auto)包含着两个小的div第一 ...