前言:本文重点在第4部分,Android中Base64算法的使用,主要是介绍android.util.Base64类,其他为对Base64原理的讲解,不关心原理的小伙伴,可直接阅读第4部分

1.何为Base64?

Base64并不是一种加密算法,而是一种转码算法。它把字节序列按照映射表转码为便于传输的64个可见字符,降低数据出错率。这也是它的名字的由来,即“基于64个字符”之意。通常我们在将数据加密后,经过Base64转码后再进行传输。按照Base64算法转码后的字节,通过逆运算可以得到原始字节,至于原始字节代表的含义,并不关心,也就是说,可以转码的数据并不限于文本,但转码结果均是64个可打印字符组成的序列(末尾可能出现1或2个“=”字符,其含义后续说明)。

2.Base64映射表

3.Base64转码规则

Base64转码把3个8位字节(3*8=24)转化为4个6位区块(4*6=24,因为Base64算法的最大映射值为63,用6个比特位即可表示),之后在每个6位区块的前面补两个0,形成一个8位字节。 如果剩余字节数不足3个,则用0填充(该字节映射为字符'=',所以转码后结尾可能有一或两个'='字符)。

按照上述规则处理后,按照映射表,求出每个字节的对应的Base64字符,例如,假设第一个字节的位序列为00000011,也就是3,根据映射表3对应'D',所以这个字节转码后用字符D表示。

注意:在转码成Base64字符后,这些字符序列是按照ASCII字符集存储,‘D’对应的ASCII码值为68,所以存为01000100,而不是3(00000011),很多初学者以为映射表中的码值就是转码后字符的字节值,这是不对的,映射表中的码值是对“分区块”处理后的每个字节映射转换Base64字符时所用。顺便附上ASCII表(打印字符部分):

数据还原时,先把Base64字符按照ASCII字符集转换成字节,然后进行“分区处理”的逆运算,得到原始字节。

4.☆Android中的使用

终于到了本文重点了,理解原理固然如有神助,运用才是硬道理。我看到很多android小伙伴都自行编写Base64处理类,或者网上找个现成的Base64工具类,其实大可不必。Android内置了Base64的处理。有的小伙伴担心自己的后台不是Java后台,其实Base64是一种算法,是与语言不相关的,每种语言都会有自己对应的实现,得到的结果是一致的。有时前端和后台解码后的数据之所以不一致,并非语言不通所致,而是一些Base64处理规则没有保持一致,比如,若结尾有‘=’字符,是否略去,等等。当然这些后续也会提到,闲话少叙,直接上代码。

android.util 包下的Base64类提供了一些静态方法:

(1)public static byte[]  encode(byte[] input, int flags);

将字节数组进行转码,得到转码后的字节数组(Base64字符对应的ASCII字节值)。

(2)public static byte[]  encode(String str, int flags);

将一个字符串进行转码,该方法等价于Base64.encode(str.getBytes(),flags);

(3)public static String  encodeToString(byte[] input, int flags) ;

将字节数组转码成Base64字符。我们看一下它的实现:

    public static String encodeToString(byte[] input, int flags) {try {return new String(encode(input, flags), "US-ASCII");} catch (UnsupportedEncodingException e) {// US-ASCII is guaranteed to be available.throw new AssertionError(e);}}

该方法实际上是将上一个方法的结果转成字符,我们看到它转换成字符时,传入的字符集的确是ASCII,这也印证了前面的说法。

(4)public static byte[] decode(byte[] input, int flags);

将转码后的字节还原成原始字节。

(5)public static byte[] decode(String str, int flags);

将Base64字符序列还原成原始字节。看一看它的实现:

    public static byte[] decode(String str, int flags) {return decode(str.getBytes(), flags);}

博主很久以前看到实现的时候比较疑惑,按照我前面的说法,不应该先按ASCII字符集转成字节值吗,后来才明白,原来UTF-8、GBK、gb2312、ISO_8859_1字符集中,这64个字符的对应的字节值以及所占用的字节数与ASCII完全一样。所以str.getBytes()与str.getBytes("US-ASCII")等效。我们打印下来看看。

先写段测试代码:

我用Base64在线转码工具得到 “我爱你android”的转码字符序列:5oiR54ix5L2gYW5kcm9pZA==

咱们以此字符串作为测试,看看不同字符集对应的字节值和占用字节数:

private static final String TAG = "朱志强";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String testStr = "5oiR54ix5L2gYW5kcm9pZA==";Log.d(TAG,"测试字符串为:" + testStr);try {Log.d(TAG,"UTF-8: 字节总数->" + testStr.getBytes().length + "\n  字节值-"+ Arrays.toString(testStr.getBytes()));Log.d(TAG,"GBK: 字节总数->" + testStr.getBytes("GBK").length + "\n  字节值-"+ Arrays.toString(testStr.getBytes("GBK")));Log.d(TAG,"gb2312: 字节总数->" + testStr.getBytes("gb2312").length + "\n  字节值-"+ Arrays.toString(testStr.getBytes("gb2312")));Log.d(TAG,"ISO_8859_1: 字节总数->" + testStr.getBytes("ISO_8859_1").length + "\n  字节值-"+ Arrays.toString(testStr.getBytes("ISO_8859_1")));Log.d(TAG,"US-ASCII: 字节总数->" + testStr.getBytes("US-ASCII").length + "\n  字节值-"+ Arrays.toString(testStr.getBytes("US-ASCII")));Log.d(TAG,"Unicode: 字节总数->" + testStr.getBytes("Unicode").length + "\n  字节值-"+ Arrays.toString(testStr.getBytes("Unicode")));} catch (UnsupportedEncodingException e) {e.printStackTrace();}}

输出的结果为:

朱志强: 测试字符串为:5oiR54ix5L2gYW5kcm9pZA==朱志强: UTF-8: 字节总数->24字节值-[53, 111, 105, 82, 53, 52, 105, 120, 53, 76, 50, 103, 89, 87, 53, 107, 99, 109, 57, 112, 90, 65, 61, 61]朱志强: GBK: 字节总数->24字节值-[53, 111, 105, 82, 53, 52, 105, 120, 53, 76, 50, 103, 89, 87, 53, 107, 99, 109, 57, 112, 90, 65, 61, 61]朱志强: gb2312: 字节总数->24字节值-[53, 111, 105, 82, 53, 52, 105, 120, 53, 76, 50, 103, 89, 87, 53, 107, 99, 109, 57, 112, 90, 65, 61, 61]朱志强: ISO_8859_1: 字节总数->24字节值-[53, 111, 105, 82, 53, 52, 105, 120, 53, 76, 50, 103, 89, 87, 53, 107, 99, 109, 57, 112, 90, 65, 61, 61]朱志强: US-ASCII: 字节总数->24字节值-[53, 111, 105, 82, 53, 52, 105, 120, 53, 76, 50, 103, 89, 87, 53, 107, 99, 109, 57, 112, 90, 65, 61, 61]朱志强: Unicode: 字节总数->50字节值-[-1, -2, 53, 0, 111, 0, 105, 0, 82, 0, 53, 0, 52, 0, 105, 0, 120, 0, 53, 0, 76, 0, 50, 0, 103, 0, 89, 0, 87, 0, 53, 0, 107, 0, 99, 0, 109, 0, 57, 0, 112, 0, 90, 0, 65, 0, 61, 0, 61, 0]

可以看到,结果与之前所说一致,同时也看到Unicode却不具备这种情况。Java代码中字符串默认以Unicode编码,咱们看一下Java中类似的代码是如何处理的:这里说明一点,Java中的Base64位于java.util包下,Android剔除了该类,后者的Base64类位于android.util包下。

Base64.getDecoder().decode("5oiR54ix5L2gYW5kcm9pZA==");

走进它的源码:

        public byte[] decode(String src) {return decode(src.getBytes(StandardCharsets.ISO_8859_1));}

可以看到,它并没有像Android一样直接调用src.getBytes(),Unicode与ASCII对这64个字符编码的字节值和占用字节数并不一样,而是传入字符集ISO_8859-1,效果与ASCII等价。

5.flag参数的含义

Android中的四个静态方法都有一个int型flags参数,它们的值可以是如下几种:

(1)DEFAULT 这个参数是默认,使用默认的方法来加密

(2)NO_PADDING 这个参数是略去加密字符串最后的”=”

(3)NO_WRAP 这个参数意思是略去所有的换行符(设置后CRLF就没用了)

(4)CRLF 这个参数看起来比较眼熟,它就是Win风格的换行符,意思就是使用CR LF这一对作为一行的结尾而不是Unix风格的LF

(5)URL_SAFE 这个参数意思是加密时不使用对URL和文件名有特殊意义的字符来作为加密字符,具体就是以-和_取代+和/

Android数据传输加密(一):Base64转码算法相关推荐

  1. 数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请注明出处:http://blog.csdn.net/chay_chan/article/details/58605605 数据 ...

  2. 数据传输加密非对称加密算法以及对称算法-RSA+AES

    转载:http://blog.csdn.net/chay_chan/article/details/58605605 源码:https://github.com/Javen205/IJPay 数据传输 ...

  3. pythondes加密盒子_PYTHON实现DES加密及base64源码

    要求是实现DES加密,解密,我是用python实现的,还是有挺多坑的,改bug就改了挺久,加密实现后,解密过程就比较轻松. 另外,附加base64编码源码 要求:输入秘钥为64位二进制数(有效位为56 ...

  4. Android数据传输加密

    对称加密 采用单密钥加密,加解密密钥同一份 代表算法:DES.3DES.AES.RC2.RC4 优点:加解密效率高,算法简单,适合加密大量数据. 缺点:密钥维护复杂,泄漏后就没有安全性可言 非对称加密 ...

  5. JAVA加密解密之消息认证码算法(Message Authentication Code,MAC)

    消息认证码算法简介 在密码学中,消息认证码(英语:Message authentication code,缩写为MAC),又译为消息鉴别码.文件消息认证码.讯息鉴别码.信息认证码,是经过特定算法后产生 ...

  6. 一种基于加密域的数字图像水印算法的设计与实现(附Matlab源码)

    一种基于加密域的数字图像水印算法的设计与实现 项目介绍 毕设项目 题目:一种基于加密域的数字图像水印算法的设计与实现 随着数字媒体技术的发展,数字媒体版权的保护得到了越来越多人的重视,数字水印技术作为 ...

  7. 三种加密方式: sha1加密、MD5加密、Base64加密 (附H5源码和js源码)

    js的加密没特别多的办法,常见的就三种, MD5加密.Base64加密和sha1加密 一. sha1加密 H5源码: <!DOCTYPE html> <html><hea ...

  8. Android安全加密:对称加密

    Android安全加密专题文章索引 Android安全加密:对称加密 Android安全加密:非对称加密 Android安全加密:消息摘要Message Digest Android安全加密:数字签名 ...

  9. Android安全加密

    转: 1) Android安全加密:数字签名和数字证书 2) Android安全加密:对称加密 3) Android安全加密:非对称加密 Android安全加密专题文章索引 Android安全加密:对 ...

最新文章

  1. 新型智能电视攻击,9成国外设备或受影响
  2. ffmpeg连接超时与解码超时
  3. 鹅厂顶级产品课程:产品细节中的情感化设计
  4. IO中的阻塞、非阻塞、同步、异步概念分析详解
  5. python错误怎么处理_python报的错误怎么处理
  6. 数据结构(复习)--------关于平衡二叉树(转载)
  7. IntelliJ IDEA 2021.1更新了好多实用功能,赶紧下载吧!
  8. linux查看分区树形状态,查看Linux磁盘的分区状态(lsblk、blkid、parted)
  9. Kafka 分布式消息系统 基础概念剖析
  10. 编译原理活动记录(虎书)
  11. numpy与tensorflow中的广播(broadcast)机制
  12. SQL2008触发器
  13. B站 汇编语言 视频 教程
  14. 源码编辑器怎么编出游戏_编辑游戏
  15. A Primer on Memory Consistency and Cache Coherence—第五章 Relaxed Memory Model
  16. android 腾讯云聊天,腾讯云视频通话
  17. office安装下载
  18. ndvi matlab,基于Matlab的NDVI最大合成
  19. Hyperic HQ简介
  20. 微信小程序~textarea字数限制与计算

热门文章

  1. CF1619B Squares and Cubes
  2. Metasploit(二)
  3. SAP CDS 开发和Fiori App生成学习笔记
  4. PhpStorm 配置 Xdebug调试工具
  5. 关于SpringMVC运行项目时出现404错误
  6. React 使用Markdown 更改样式
  7. 百度CTO王海峰:亚洲丰富实践场景推动AI技术落地探索
  8. 计算机制作效果图常用软件有,计算机园林效果图有哪些绘制过程?
  9. 从事手机软件开发需要掌握什么知识
  10. 如何使用友盟统计(自定义事件)