当前位置:   article > 正文

java实现Base64编码与解码_base64.tobase64string没有了

base64.tobase64string没有了


前言

Base64算法并不是真正意义上的加密算法。不过在加密与解密方面经常看到它的身影,比如Base64算法常作为密钥、密文和证书的的一种通用存储编码格式。这是笔者在加解密算法这一系列文章中引入它的原因。


一、Base64的3种实现方式

1.Jdk8实现

public class JdkBase64 {
    public static void main(String[] args) {
        String encode = jdkBase64Encode();
        jdkBase64Decode(encode);
    }

    private static String jdkBase64Encode() {
        String result = Base64.getEncoder().encodeToString("helloWorld".getBytes(StandardCharsets.UTF_8));
        System.out.println(result);
        return result;
    }

    private static void jdkBase64Decode(String src) {
        byte[] decode = Base64.getDecoder().decode(src.getBytes(StandardCharsets.UTF_8));
        System.out.println(new String(decode, StandardCharsets.UTF_8));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.Bouncy Castle实现

引入jar包

<dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-jdk15on</artifactId>
     <version>1.67</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

代码

public class CastleBase64 {
    public static void main(String[] args) {
        String encode = encode();
        decode(encode);
    }

    private static String encode() {
        String result = Base64.toBase64String("helloWorld".getBytes(StandardCharsets.UTF_8));
        System.out.println(result);
        return result;
    }

    private static void decode(String src) {
        byte[] decode = Base64.decode(src.getBytes(StandardCharsets.UTF_8));
        System.out.println(new String(decode, StandardCharsets.UTF_8));
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.Commons Codec实现

引入jar包

<dependency>
   <groupId>commons-codec</groupId>
   <artifactId>commons-codec</artifactId>
   <version>1.14</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

代码

public class CodecBase64 {
    public static void main(String[] args) {
        String encodeStr = encode();
        System.out.println(encodeStr);
        decode(encodeStr);
    }

    private static String encode() {
        byte[] result = Base64
                .encodeBase64("helloWorld".getBytes(StandardCharsets.UTF_8));
        return new String(result, StandardCharsets.UTF_8);
    }

    private static void decode(String encodeStr) {
        byte[] decode = Base64.decodeBase64(encodeStr);
        System.out.println(new String(decode, StandardCharsets.UTF_8));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

二、什么是Base64算法

Base64算法是一种基于64个字符的编码算法,根据RFC2045的定义:

The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.

经过Base64编码后的数据会比原来数据略长,为原来的4/3倍。编码后的字符串的字符数是以4位单位的整数倍。
在RFC 2045文件中给出的字符映射表如下:
在这里插入图片描述
这张字符映射表中,Value指的是十进制编码,Encoding指的是字符,共映射了64个字符,这也是该算法命名的由来。映射表的最后一个字符是等号,是用来补位的,看到有一串字符以等号结尾的,基本上会联想到Base64

三、原理简述

Base64算法主要是将给定的字符以字符编码(如ASCII码,UTF-8)对应的十进制为基准,做编码操作:

  1. 将给定的字符串转换成对应的字符编码(如ASCII码)
  2. 将获得的字符编码转换成二进制码
  3. 对获得的二进制码做分组转换:每3个8位二进制码为一组,转换为每4个6位的二进制码(不足6位补0)
  4. 对获得4-6二进制码进行补位,向6位二进制码添加2位高位0,组成4个8位二进制码
  5. 将获得的4-8二进制码转换成十进制码
  6. 将获得的十进制码转换成Base64字符表中对应的字符。

1.ASCII字符编码推导

步骤结果
原文字符B
ASCII码66
8位二进制码01000010
4-6二进制码010000 100000
4-8二进制码00010000 00100000
十进制码16 32
字符表映射码Q g
进行补位Qg==

当原文的二进制码长度不足24位,最终转换成十进制码时也不足4项,就需要用等号补位


2.非ASCII码字符推导

ASCII码可以表示十进制范围为0~127的字符,对应的二进制范围是0000 0000 ~ 0111 1111。ASCII码包括阿拉伯数字、大小写英文字母和一些控制符,没有包含双字节编码的字符如中文字符。UTF-8编码使用3个字节表示一个汉字。
下面对中文进行推导

步骤结果
原文字符
UTF-8码字节-27 -91 -67
8位二进制码11100101 10100101 10111101
4-6二进制码111001 011010 010110 111101
4-8二进制码00111001 00011010 00010110 00111101
十进制码57 26 22 61
字符表映射码5aW9

3.推导工具类

按照以上的步骤,可以使用以下工具类,找到转换后的十进制码,最后在对照Base64编码表,即可得到映射码。最后结果可以以上面提到的实现方式进行比较。

public class BinaryUtil {
    public static void main(String[] args) {
        byte[] bytes = utfByte("好"); // 根据utf-8编码字节
        for (byte eachByte : bytes) {
            String binary = byteToBinary(eachByte); // 转换成二进制
            System.out.println(eachByte + ":" + binary);
        }
        System.out.println(binaryToDecimal("00011010")); // 二进制装换成十进制
    }

    public static byte[] utfByte(String msg) {
        return msg.getBytes(StandardCharsets.UTF_8);
    }

    public static String byteToBinary(byte src) {
        return Integer.toBinaryString((src & 0xFF) + 0x100).substring(1);
    }

    public static Map<Byte, String> stringToBinary(String src) {
        Map<Byte, String> result = new HashMap<Byte, String>();
        for (byte each : src.getBytes()) {
            result.put(each, byteToBinary(each));
        }
        return result;
    }

    public static int binaryToDecimal(String src) {
        return Integer.parseInt(src, 2);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

总结

Base64加密解密经常用到。不过其并不是真正意义上的加密解密算法。通过上面的原理推导,知道一串Base64编码的字符串完成能够找到其原码。所以,对于实际需要传输个人数据和敏感信息,Base64不适用此场景。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/202926
推荐阅读
相关标签
  

闽ICP备14008679号