Java 8 新特性|java.util.Base64 编码解码

一、Base64背景

在 Java 6 ( JDK 1.6 ) 之前, JDK 一直没有包含 Base64 的实现类。因此大部分人都使用 Sum/Orale JDK 里面的 sun.misc.BASE64Encode 和sun.misc.BASE64Decode。然后这也成为很多 Java 开发者的习惯。一直沿用到今天的 Java8 中还有人在用。

JDK 1.6 虽然添加了 Base64 的实现。但是,非常隐秘,竟然是在 javax.xml.bind 包下的 DatastypeConvert 类中的两个静态方法 parseBase64Binary 和 printBase64Binary.

Java 8 终于把 Base64 扶正了,在 java.util 包下提供了 Base64 类用于编码和解码 Base64 数据。

二、Java 8 Base64简介

Java 8 中的 java.util.Base64 类提供了三种类型的 Base64 编码解码格式:

1、 简单类型( simple ) : 编码字符只包含 A-Za-z0-9+/ 等 64 个字符。且编码的时候不会包含任何换行符 ( \r 、 \n 、\r\n )。解码的时候也只会解码 A-Za-z0-9+/ 内的字符,超出的则会被拒绝。
2、 URL : 编码字符只包含 A-Za-z0-9+_ 等 64 个字符。和 简单 相比,就是把 / 换成了 _ 。因为没有 / 字符,因此这种编码方式非常适合 URL 和文件名等。
3、 MIME : 编码会被映射为 MIME 友好格式:每一行输出不超过 76 个字符,而且每行以 \r\n 符结束。但末尾行并不会包含 \r\n

三、内部类

java.util.Base64 还包含了两个内部静态类,分别实现了 RFC 4648 和 RFC 2045 中规范的 Base64 编码和解码方式。

              内部类
                                  说明
static class Base64.Decoder该类实现使用 RFC 4648 和 RFC 2045 中规定的 Base64 解码方案解码数据
static class Base64.Encoder该类实现使用 RFC 4648 和 RFC 2045 中规定的 Base64 编码方案编码数据

四、静态方法

java.util.Base64 类提供的都是静态方法

//返回一个 Base64.Decoder 类型的 简单 解码器
public static Decoder getDecoder() {
   return Decoder.RFC4648;
}
//返回一个 Base64.Encoder 类型的 简单 编码器
public static Encoder getEncoder() {
   return Encoder.RFC4648;
}
//返回一个 Base64.Decoder 类型的 MIME 解码器
public static Decoder getMimeDecoder() {
   return Decoder.RFC2045;
}
//返回一个 Base64.Encoder 类型的 MINE 编码器
public static Encoder getMimeEncoder() {
   return Encoder.RFC2045;
}
//返回一个 Base64.Encoder 类型的使用特定长度和行分隔符的 MINE 编码器
public static Encoder getMimeEncoder(int lineLength, byte[] lineSeparator) {
       Objects.requireNonNull(lineSeparator);
       int[] base64 = Decoder.fromBase64;
       for (byte b : lineSeparator) {
           if (base64[b & 0xff] != -1)
               throw new IllegalArgumentException(
                    "Illegal base64 line separator character 0x" + Integer.toString(b, 16));
        }
        if (lineLength <= 0) {
            return Encoder.RFC4648;
        }
        return new Encoder(false, lineSeparator, lineLength >> 2 << 2, true);
}
//返回一个 Base64.Decoder 类型的 URL 和文件名安全的解码器
public static Decoder getUrlDecoder() {
   return Decoder.RFC4648_URLSAFE;
}
//返回一个 Base64.Encoder 类型的 URL 和文件名安全的编码器public static Encoder getUrlEncoder() {
   return Encoder.RFC4648_URLSAFE;
}

五、代码范例(一)基本的编码解码器

getDecoder() 和 getEncoder() 方法

package com.sjh.test.java8.base64;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class Base64Test1 {

    public static void main(String args[]) {

        try {
            String base64encodedString = Base64.getEncoder().encodeToString(
                    "Java 8 Base64 编码解码 - Java8新特性 - 二哥!".getBytes("utf-8"));
            System.out.println(base64encodedString);

            System.out.println();

            byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);

            System.out.println(new String(base64decodedBytes, "utf-8"));

        } catch(UnsupportedEncodingException e) {
            System.out.println("异常:" + e.getMessage());
        }
    }
}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.base64.Base64Test1
SmF2YSA4IEJhc2U2NCDnvJbnoIHop6PnoIEgLSBKYXZhOOaWsOeJueaApyAtIOS6jOWTpe+8gSA=

Java 8 Base64 编码解码 - Java8新特性 - 二哥!

Process finished with exit code 0

六、代码范例(二)URL 和文件名安全的编码解码器

getUrlEncoder()  getUrlDecoder() 方法

package com.sjh.test.java8.base64;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class Base64Test2 {

    public static void main(String args[]) {

        try {
            String base64encodedString = Base64.getUrlEncoder().encodeToString(
                    "Java 8 Base64 编码解码 - Java8新特性 - 二哥!".getBytes("utf-8"));
            System.out.println(base64encodedString);

            System.out.println();

            byte[] base64decodedBytes = Base64.getUrlDecoder().decode(base64encodedString);

            System.out.println(new String(base64decodedBytes, "utf-8"));

        } catch(UnsupportedEncodingException e) {
            System.out.println("异常:" + e.getMessage());
        }
    }

}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.base64.Base64Test2
SmF2YSA4IEJhc2U2NCDnvJbnoIHop6PnoIEgLSBKYXZhOOaWsOeJueaApyAtIOS6jOWTpe-8gSA=

Java 8 Base64 编码解码 - Java8新特性 - 二哥!

Process finished with exit code 0

七、代码范例(三)MIME Base64 编码解码器

getMimeEncoder() 和 getMimeDecoder() 无参方法

package com.sjh.test.java8.base64;

import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.UUID;

public class Base64Test3 {
    public static void main(String args[]) {

        try {

            StringBuilder stringBuilder = new StringBuilder();

            for (int i = 0; i < 10; ++i) {
                stringBuilder.append(UUID.randomUUID().toString());
            }

            byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
            String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
            System.out.println(mimeEncodedString);
            System.out.println();

            byte[] base64decodedBytes = Base64.getMimeDecoder().decode(mimeEncodedString);

            System.out.println(new String(base64decodedBytes, "utf-8"));

        } catch(UnsupportedEncodingException e) {
            System.out.println("异常:" + e.getMessage());
        }
    }
}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.base64.Base64Test3
NjIyMTFlOGYtMDNlMi00NjFlLTgxOWYtMmZhNzk5NTYxOGMxNzIxYTQ3ZjEtMDk1Ni00OTM4LWIw
MjQtMTQwYmQ5YzQ1NjZjNDhjOTU5YzQtODI4OC00ZWE4LTg5ZDQtZTFiMjkxZGYyOGY1ZjYzMzNi
YTUtMTcyOC00NjUxLWE1MTQtNzU3NWRiMjJiMTc5ZjgyODZjYTctNWYyNS00YTU3LTlhNDctZDdk
M2Y4MDdiNjlkZTExN2YyODMtYjkzYi00YmRhLThlZWItZTZiNWYzZDUzMjJkYWI1ZDNlNWQtMjEz
NS00MDRmLWIzZmMtNzVhNDQyMjRiM2U5ZDcxZjE0ZjAtZTBlOC00MjEwLTlkYzYtOTJmZmQ4Njc2
ZTI2OGIyNzRmNmUtNDZkOS00NGFhLThjMTEtYTlhNjBhMDQwYTQzNDFkODBlNDQtYThiYS00ODcz
LTkzODgtMTA2MGNmODcyYTY5

62211e8f-03e2-461e-819f-2fa7995618c1721a47f1-0956-4938-b024-140bd9c4566c48c959c4-8288-4ea8-89d4-e1b291df28f5f6333ba5-1728-4651-a514-7575db22b179f8286ca7-5f25-4a57-9a47-d7d3f807b69de117f283-b93b-4bda-8eeb-e6b5f3d5322dab5d3e5d-2135-404f-b3fc-75a44224b3e9d71f14f0-e0e8-4210-9dc6-92ffd8676e268b274f6e-46d9-44aa-8c11-a9a60a040a4341d80e44-a8ba-4873-9388-1060cf872a69

Process finished with exit code 0

看不出来有 76 个字符分割

getMimeEncoder() 和 getMimeDecoder() 有参重载方法

package com.sjh.test.java8.base64;

import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.UUID;

public class BaseTest4 {

    public static void main(String args[]) {

        try {

            StringBuilder stringBuilder = new StringBuilder();

            for (int i = 0; i < 10; ++i) {
                stringBuilder.append(UUID.randomUUID().toString());
            }

            byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
            String mimeEncodedString = Base64.getMimeEncoder(32,"@~@\n\n".getBytes("utf-8")).encodeToString(mimeBytes);
            System.out.println(mimeEncodedString);
            System.out.println();

            byte[] base64decodedBytes = Base64.getMimeDecoder().decode(mimeEncodedString);

            System.out.println(new String(base64decodedBytes, "utf-8"));

        } catch(UnsupportedEncodingException e) {
            System.out.println("异常:" + e.getMessage());
        }
    }
}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.base64.BaseTest4
MmIxZGFhMzktYjc1ZS00ZWFiLWIyYTMt@~@

YjVjNjJmMmQ4ZGRmYjE0NzI3Y2EtNTJk@~@

Yi00ZmZkLWE2NDMtMmZhM2RlMWNlMzk2@~@

YjlmYjViMDAtYjBmMi00NWYyLWE3NDkt@~@

Y2JjZTMxZjZkYjQ5MGYxMTI1YWQtMDQ2@~@

YS00M2UzLTkzMDgtMTFlZWE2MjFjMGQy@~@

NWNiMGE3YmMtYzM3Mi00M2EzLWE2OWMt@~@

ODczZGJmNTAzNzA5MjBiNzdlNjctNWU5@~@

OC00ZDUzLWI3MjAtNWJkMjM0ZjcyMGQy@~@

MDY0YzJlOTEtYzRkNi00NGRmLWFhYjAt@~@

NjIzNTBmMTRhOWQ5YTFiYzcwYmEtMTI1@~@

MC00OWIwLWJhZDktMDkzZGVjZjk3Nzcx@~@

YTIwZGUxYzItNmNiNy00ZTVlLWI4Njkt@~@

ZjA4YTdlNGFlY2RjNjlkZTZkYmItN2Q0@~@

Mi00YTU0LWEzYTUtZDAzYTFkMGYwNmM2

2b1daa39-b75e-4eab-b2a3-b5c62f2d8ddfb14727ca-52db-4ffd-a643-2fa3de1ce396b9fb5b00-b0f2-45f2-a749-cbce31f6db490f1125ad-046a-43e3-9308-11eea621c0d25cb0a7bc-c372-43a3-a69c-873dbf50370920b77e67-5e98-4d53-b720-5bd234f720d2064c2e91-c4d6-44df-aab0-62350f14a9d9a1bc70ba-1250-49b0-bad9-093decf97771a20de1c2-6cb7-4e5e-b869-f08a7e4aecdc69de6dbb-7d42-4a54-a3a5-d03a1d0f06c6

Process finished with exit code 0

end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小技巧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值