Base64编码和解码算法
Base64么新鲜的算法了。只是假设你没从事过页面开发(或者说动态页面开发。尤其是邮箱服务),你都不怎么了解过,仅仅是听起来非常熟悉。
对于黑客来说,Base64与MD5算法有着相同的位置。由于电子邮箱(e-mail)正文就是base64编码的。
那么。我们就一起来深入的探讨一下这个东东吧。
对于一种算法,与其问“它是什么?”,不如问“它实现了什么?”
Base64实现了:将随意字节转为可读字符的编码。
我们知道。除了页面上的文本,计算机中的数据还有非常多是不可见的。那么我们再扯一扯编码的问题吧。
通俗的说,编码就是给某个文字符号边上一个数字序号,计算机在现实这个文字符号(字符)的时候,依据这个序号到字库中查找相应的点阵或矢量数据,
在显示器上“画”出来。(关于点阵和矢量我们就不扯了。不然就真的太远了。
)
起初的字符编码,没有把汉字、日文、朝鲜文和其它文字包含在内,仅仅有26个英文字母的大写和小写和10个阿拉伯数字。加上一些控制字符和空格,用一个字节
就行全然的编码了。(不要告诉我你不知道2的7次方和2的8次方是多少,一个技术人员为这种问题困扰简直是一种耻辱。)
然而。世界上除了文字还有数据。比方图片、压缩文件、程序等等都是二进制文件。这些文件一样以字节为单位存储数据。这些字节往往不不过2的7次方以内
的可显示的文字字符编码,还有可能是大于127(有符号数小于0)的字节,这些字节没办法用字符显示出来,Base64就是通过某种算法将他们显示出来。
*那么,Base64加密是安全的吗?
没有绝对安全的加密。Base64不是为了安全,而是为了显示。并且Base64是可逆的。也就是说。通过简单的解密就能得到原文。事实上即便是不可逆的MD5算法。
也能够通过明文数据库找出可能的原文(睡到知道e10adc3949ba59abbe56e057f20f883e的原文就是123456)。
*那么,Base64是怎么实现的呢?
事实上非常easy,只是为了URL等特殊用处,Base64选择了下面64个字符作为密文显示,着64个字符都是可显示的,他们是:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
假设密文有不属于他们的字符,那么不是Base64编码或者是山寨版的。
一眼看去就知道是26个字母大写和小写和数字,加上“+”“/”两个符号。“?
*-”因为正則表達式的问题,没有选用,而空格和回车这些是不能显示的。
Base64处理的过程是,以3个字节为一组(3个字节就是24位嘛),每6位扩展成8位得到4个字节(就是32位):
11111111 11111111 11111111 -> 111111 111111 111111 111111 -> 00111111 00111111 00111111 00111111
那么,得到的每个字节,最大也就是2的6次方。
或许你说:哇,小于2的7次方,能够显示了。
事实上不是,得到的这2的6次方式上面那一串字符的索引,也就是说每一个字节的值仅仅是代表它在密文表中的位置。比方
字符“a”的编码是97。 用16进制表示是0x61(VB表示为&H61)。二进制:01100001,由于不足3位。补0得到 00011000 00010000 000……
前两个字节是十进制的24 和 16,那么相应那一串字符中的第24个字符和第16个字符为:YQ(索引从0開始算),那么单独“a”的Base64编码为
YQ==(不足3为的每一个字符直接转为“=”)。简单吧!
有了算法,解码的过程就各位聪明特达的程序猿取思考思考吧,最后C/C++版的编码和解码代码贴上。
- /******************************************
- Base64编码解码算法 C语言源码
- by 虎胆游侠 http://blog.csdn.net/prsniper
- ******************************************/
- #include <stdio.h> //注意哦,VC中""是当前路径。<>是系统路径
- #include <windows.h>
- const char BASE_CODE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- //编码,參数:要编码的字符串指针,解码后存放的位置(编码字串长度的4/3),要编码的字符串长度 ->返回结果长度
- int fnBase64Encode(char *lpString, char *lpBuffer, int sLen)
- { register int vLen = 0; //寄存器局部变量,提速
- while(sLen > 0) //处理整个字符串
- { *lpBuffer++ = BASE_CODE[(lpString[0] >> 2 ) & 0x3F]; //右移两位,与00111111是防止溢出,自加
- if(sLen > 2) //够3个字符
- { *lpBuffer++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)];
- *lpBuffer++ = BASE_CODE[((lpString[1] & 0xF) << 2) | (lpString[2] >> 6)];
- *lpBuffer++ = BASE_CODE[lpString[2] & 0x3F];
- }else
- { switch(sLen) //追加“=”
- { case 1:
- *lpBuffer ++ = BASE_CODE[(lpString[0] & 3) << 4 ];
- *lpBuffer ++ = '=';
- *lpBuffer ++ = '=';
- break;
- case 2:
- *lpBuffer ++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)];
- *lpBuffer ++ = BASE_CODE[((lpString[1] & 0x0F) << 2) | (lpString[2] >> 6)];
- *lpBuffer ++ = '=';
- break;
- }
- }
- lpString += 3;
- sLen -= 3;
- vLen +=4;
- }
- *lpBuffer = 0;
- return vLen;
- }
- //子函数 - 取密文的索引
- inline char GetCharIndex(char c) //内联函数能够省去函数调用过程。提速
- { if((c >= 'A') && (c <= 'Z'))
- { return c - 'A';
- }else if((c >= 'a') && (c <= 'z'))
- { return c - 'a' + 26;
- }else if((c >= '0') && (c <= '9'))
- { return c - '0' + 52;
- }else if(c == '+')
- { return 62;
- }else if(c == '/')
- { return 63;
- }else if(c == '=')
- { return 0;
- }
- return 0;
- }
- //解码,參数:结果,密文,密文长度
- int fnBase64Decode(char *lpString, char *lpSrc, int sLen) //解码函数
- { static char lpCode[4];
- register int vLen = 0;
- if(sLen % 4) //Base64编码长度必然是4的倍数,包含'='
- { lpString[0] = '\0';
- return -1;
- }
- while(sLen > 2) //不足三个字符。忽略
- { lpCode[0] = GetCharIndex(lpSrc[0]);
- lpCode[1] = GetCharIndex(lpSrc[1]);
- lpCode[2] = GetCharIndex(lpSrc[2]);
- lpCode[3] = GetCharIndex(lpSrc[3]);
- *lpString++ = (lpCode[0] << 2) | (lpCode[1] >> 4);
- *lpString++ = (lpCode[1] << 4) | (lpCode[2] >> 2);
- *lpString++ = (lpCode[2] << 6) | (lpCode[3]);
- lpSrc += 4;
- sLen -= 4;
- vLen += 3;
- }
- return vLen;
- }
- void main() //主函数,測试函数
- { char s[] = "a", str[32];
- int l = strlen(s);
- int i = fnBase64Encode(s, str, l);
- printf("fnBase64Encode(\"%s\", str, %d) = \"%s\";\n", s, l, str);
- l = fnBase64Decode(s, str, i);
- printf("fnBase64Decode(\"%s\", s, %d) = \"%s\";\n", str, i, s);
- }
编译为控制台应用程序,执行如图:

原文地址:http://blog.csdn.net/prsniper/article/details/7097643
版权声明:本文博主原创文章,博客,未经同意不得转载。
Base64编码和解码算法的更多相关文章
- SSE图像算法优化系列三十一:Base64编码和解码算法的指令集优化。
一.基础原理 Base64是一种用64个Ascii字符来表示任意二进制数据的方法.主要用于将不可打印的字符转换成可打印字符,或者简单的说是将二进制数据编码成Ascii字符.Base64也是网络 ...
- js的Base64编码与解码
js的Base64编码与解码 pc和手机app项目中,经常需要将手机自带的表情图片转换特定的编码格式与后台进行交互. Base64其实是一种简单的置换加密方式,但是BASE64的用处往往并不是为了防止 ...
- Java 8中的Base64编码和解码
转自:https://juejin.im/post/5c99b2976fb9a070e76376cc Java 8会因为将lambdas,流,新的日期/时间模型和Nashorn JavaScript引 ...
- Base64编码与解码原理
Base64编码是使用64个可打印ASCII字符(A-Z.a-z.0-9.+./)将任意字节序列数据编码成ASCII字符串,另有“=”符号用作后缀用途. base64索引表 base64编码与解码的基 ...
- BASE64编码和解码(VC源代码) 并 内存加载 CImage 图像
BASE64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本.完整的BASE64定义可见 RFC1421和 RFC2045.编码后的数据比原始数据略长,为原来的4/3.在电子 ...
- base64编码、解码的C语言实现
转自:http://www.cnblogs.com/yejianfei/archive/2013/04/06/3002838.html base64是一种基于64个可打印字符来表示二进制数据的表示方法 ...
- android Java BASE64编码和解码二:图片的编码和解码
1.准备工作 (1)在项目中集成 Base64 代码,集成方法见第一篇博文:android Java BASE64编码和解码一:基础 (2)添加 ImgHelper 工具类 package com.a ...
- Python中进行Base64编码和解码
Base64编码 广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容 ...
- Javascript Base64编码与解码
原文:[转]Javascript Base64编码与解码 <html> <head> <META HTTP-EQUIV="MSThemeCompatible&q ...
随机推荐
- A10 平板开发二搭建Android开发环境
我是直接在Ubuntu 12.10 64位系统下操作的,搭建Ubuntu开发环境类似,见Ubuntu 10.04开发环境配置.需要注意的是,64位的系统,需要安装支持32位的库(sudo apt-ge ...
- SpringMVC+easyUI CRUD 添加数据C
接一篇文章,今天上午实现了添加数据.以下是Jsp.里面主要是看newUser()和saveUser().注意这函数里的url,newUser()里面去掉url属性.还要注意的一个问题 <div ...
- 初始——第一款个人开发上线app store
最初学习iOS开发时就听人建议,程序员应该有自己的博客,来记录每天的收获,于人于己都是一件很有意义的事.但当初作为菜鸟一枚,自认为对一些知识的认识尚浅,写博客这种高大上的事和自己八竿子打不着. 现如今 ...
- avalon2学习心得(1)
github上,avalon2的项目描述是这样的:“avalon2是一款基于虚拟DOM与属性劫持的 迷你. 易用. 高性能 的 前端MVVM框架, 适用于各种场景, 兼容各种古老刁钻浏览器, 吸收最新 ...
- magic Ajax使用以及注意事项
以下是引用片段:一.概述 现在Ajax技术正如火如荼的在Internet上发展着.而面对我们之前开发的ASP.NET1.1的Web项目,类似于下拉框等联动也需要啪啪啪的不断刷新,的确影响到了用户 ...
- MySQL主从同步、读写分离配置步骤
现在使用的两台服务器已经安装了MySQL,全是rpm包装的,能正常使用. 为了避免不必要的麻烦,主从服务器MySQL版本尽量保持一致; 环境:192.168.0.1 (Master) 192.168. ...
- stl学习之模板
模板是实现代码重用机制的一种工具,实质就是实现类型参数化,即把类型定义为参数. C++提供两种模板:函数模板,类模板. template<typename T> //或者 templa ...
- Object.create函数
创建一个具有指定原型且可选择性地包含指定属性的对象. Object.create(prototype, descriptors) 参数 prototype必需. 要用作原型的对象. 可为 null. ...
- Java程序的成长之路
转载链接:http://www.admin10000.com/document/2901.html 互联网发展日新月异,社会科技每天都在发生着翻天覆地的变化,而程序员已经成了这个时代的庞大群体,各种各 ...
- c++连接mysql数据库(使用mysql api方式,环境VS2013+MYSQL5.6)
转载请注明出处,原文地址http://www.cnblogs.com/zenki-kong/p/4382657.html 刚开始写博客,博主还只是个大三汪,学艺不精,如有错误还请前辈指出(>^ω ...