【小工匠聊密码学】-- Base64算法

1、Base64 概述

1.1 什么是Base64编码

  可以将任意的字节数组数据,通过算法,生成只有(大小写英文、数字、+、/)(一共64个字符)内容表示的字符串数据。即将任意的内容转换为可见的字符串形式。

1.2、Base64 编码表

Base64编码表

1.3、Base64 算法由来

以前发送邮件只支持可见字符的传送。由此,需要有一个方法将不可见的字符转换为可见的字符,便产生了Base64编码算法。

1.4、Base64 与 加密关系

(1)Base 64不是加密算法,是一种编码解码算法,通过Base64编码的数据,可以解码回来。 (2) 如果把Base64 一定要把Base64 理解为加密算法的话,Base64 是公布密钥的加密算法。加密原则:公布算法,但是不公布密钥

2、Base64 算法原理

2.1 编码规则

(1)将数据按照 3个字节一组的形式进行处理,每三个字节在编码之后被转换为4个字节。(即:如果一个数据有6个字节,可编码后将包含6/3*4=8个字节) (2)当数据的长度无法满足3的倍数的情况下,最后的数据需要进行填充操作,即补“=” ,这里“=”是填充字符,不要理解为第65个字符

2.2 编码过程

编码规则 (1) 将原始数据3个一组,按位进行分割为 每6位一个字节的形式,进行转换,形成新的4个字节。这四个字节才通过Base64编码表进行映射,形成最后实际的Base64编码结果。 (2)如果原始数据最后无法凑成3个字节,则补填充,以“=”作为替换,代表没有数据。

3、Base64 算法应用

(1) Base64 JSON 二进制数据 服务器给客户端在JSON中传递二进制数据 (2) Base64 图片编码 部分小图片使用Base64进行保存。 (3)Base64 在URL中的应用 Base64 在URL编码应用时,由于'+' 和 '-' 会被浏览器进行转义,因此使用'-','_' 替换,在common codec的实现用,有将提供相应的方法。 (4)Base64编码字符显示回车换行 Base64编码,内容非常多时,common codec实现中,可以在生成Base64字符串是,长多超过指定字符串(默认76个字符串)在生成的Base64字符串中加入换行符(默认'\r\n')

4、算法实现

4.1 JDK 实现

package lzf.cipher.jdk;

import java.util.Base64;

/**
 * @author Java小工匠
 */
public class JdkBase64Utils {

    // base64 编码
    public static String base64Encoder(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    // base64 解码
    public static byte[] base64Decode(byte[] src) {
        return Base64.getDecoder().decode(src);
    }

    // base64 解码
    public static String base64DecodeToStr(byte[] src) {
        return new String(base64Decode(src));
    }

    public static void main(String[] args) {
        String base64 = base64Encoder("java小工匠".getBytes());
        System.out.println("编码:" + base64);
        String str = base64DecodeToStr(base64.getBytes());
        System.out.println("解码:" + str);
    }
}

4.2 CC 实现

package lzf.cipher.cc;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

/**
 * @author Java小工匠
 */
public class CCBase64Utils {
    // base64 编码
    public static String base64Encoder(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }

    // base64 解码
    public static byte[] base64Decode(byte[] src) {
        return Base64.decodeBase64(src);
    }

    // base64 解码
    public static String base64DecodeToStr(byte[] src) {
        return new String(base64Decode(src));
    }

    // CC base64编码,编码长度超过76个字符,添加\r\n 字符进行换行
    public static String base64EncodeToChunkedStr(byte[] data) {
        byte[] bytes = Base64.encodeBase64(data, true);
        return StringUtils.newStringUsAscii(bytes);
    }

    // 使用'-' 和 '_' 下划线替换Base64 编码中的 '+' 和 '/',解决 URL传输问题
    public static String base64EncodeToURLSafeString(byte[] data) {
        return Base64.encodeBase64URLSafeString(data);
    }

    public static void main(String[] args) {
        String base64 = base64Encoder("java小工匠".getBytes());
        System.out.println("编码:" + base64);
        String str = base64DecodeToStr(base64.getBytes());
        System.out.println("解码:" + str);
        String strNewLine = "如果base64超过76个字符,Base64编码就会产生换行,默认添加\r\n符号!";
        String ccBase64Chunked = base64EncodeToChunkedStr(strNewLine.getBytes());
        System.out.println(ccBase64Chunked);
        System.out.println("========================");
        String strUrl = "URLBase64编码,使用'-'和'_'替换'+'和'/'";
        String ccBBase64Url = base64EncodeToURLSafeString(strUrl.getBytes());
        System.out.println(ccBBase64Url);
    }
}

4.3 BC 实现

package lzf.cipher.bc;

import org.bouncycastle.util.encoders.Base64;

/**
 * @author Java小工匠
 */
public class BCBase64Utils {

    // base64 编码
    public static String base64Encoder(byte[] bytes) {
        return Base64.toBase64String(bytes);
    }

    // base64 解码
    public static byte[] base64Decode(byte[] src) {
        return Base64.decode(src);
    }

    // base64 解码
    public static String base64DecodeToStr(byte[] src) {
        return new String(base64Decode(src));
    }

    public static void main(String[] args) {
        String base64 = base64Encoder("java小工匠".getBytes());
        System.out.println("编码:" + base64);
        String str = base64DecodeToStr(base64.getBytes());
        System.out.println("解码:" + str);
    }
}

如果读完觉得有收获的话,欢迎点赞、关注、加公众号【小工匠技术圈】

原文发布于微信公众号 - 小工匠技术圈(xgn177971793771)

原文发表时间:2018-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据魔术师

数据结构-线性表|顺序表|链表(下)

1 1 1 哈喽。各位小伙伴好久不见,热心的小编赶在开学季又来给大家送上满满的干货了。祝大家开心快乐! 继上两次咱们聊了顺序表、单链表、静态链表等知识。那么热爱...

2557
来自专栏猿人谷

C++ 虚拟继承

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继 承自类A,因此在类D...

2018
来自专栏java一日一条

Java hashCode() 方法深入理解

Java.lang.Object 有一个hashCode()和一个equals()方法,这两个方法在软件设计中扮演着举足轻重的角色。在一些类中覆写这两个方法以完...

281
来自专栏Java Edge

@ConditionalOnMissingBean注解使用

2956
来自专栏Android机动车

转向Kotlin——泛型

无论是Java还是Kotlin,泛型都是一个非常重要的概念,简单的泛型应用很容易理解,不过也有理解起来麻烦的时候。一起来认识一下。

722
来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版7.4节List coredump例子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

543
来自专栏糊一笑

Immutable日常操作之深入API

写在前面 本文只是个人在熟悉Immutable.js的一些个人笔记,因此我只根据我自己的情况来熟悉API,所以很多API并没有被列举到,比如常规的push/ma...

3689
来自专栏我叫刘半仙

原荐你知道么?static关键字有5种用法。

     说到static,静态变量和静态方法大家随口就来,因为他们在实际开发中应用很广泛,但他们真正在使用的时候会存在很多问题,而且它的使用不只那两种:   ...

3666
来自专栏编程心路

你不知道的 equals 和 ==

i1 == i2 和 i1.equals(i2) 这两个都是 true,大多数人应该可以答对。后面的 i3 == i4 和 i3.equals(i4) 估计就...

582
来自专栏Golang语言社区

Go语言interface详解

interface Go语言里面设计最精妙的应该算interface,它让面向对象,内容组织实现非常的方便,当你看完这一章,你就会被interface的巧妙设计...

3569

扫码关注云+社区