base64 订阅
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。 展开全文
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。
信息
特    性
Base64编码具有不可读性
外文名
base64
定    义
8Bit字节代码的编码方式之一
可用于
在HTTP环境下传递较长的标识信息
中文名
基于64个可打印字符来表示二进制数据
属    性
编码方式
应    用
用于传输8Bit字节代码
base64简介
标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。关于这个编码的规则:①.把3个字节变成4个字节。②每76个字符加一个换行符。③.最后的结束符也要处理。转换前 11111111, 11111111, 11111111 (二进制)转换后 00111111, 00111111, 00111111, 00111111 (二进制)上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),这个表是这样的:(摘自RFC2045)转换表Table 1: The Base64 Alphabet转换前 10101101,10111010,01110110转换后 00101011, 00011011 ,00101001 ,00110110十进制 43 27 41 54对应码表中的值 r b p 2所以上面的24位编码,编码后的Base64值为 rbp2解码同理,把 rbq2 的二进制位连接上再重组得到三个8位值,得出原码。(解码只是编码的逆过程,有关MIME的RFC还有很多,如果需要详细情况请自行查找。)第一个字节,根据源字节的第一个字节处理。规则:源第一字节右移两位,去掉低2位,高2位补零。既:00 + 高6位第二个字节,根据源字节的第一个字节和第二个字节联合处理。规则如下,第一个字节高6位去掉然后左移四位,第二个字节右移四位即:源第一字节低2位 + 源第2字节高4位第三个字节,根据源字节的第二个字节和第三个字节联合处理,规则第二个字节去掉高4位并左移两位(得高6位),第三个字节右移6位并去掉高6位(得低2位),相加即可第四个字节,规则,源第三字节去掉高2位即可//用更接近于编程的思维来说,编码的过程是这样的://第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一//个目标字符。//然后将第一个字符与0x03(00000011)进行与(&)操作并左移4位,接着第二个字符右移4位与前者相或(|),即获得第二个目标字符。//再将第二个字符与0x0f(00001111)进行与(&)操作并左移2位,接着第三个字符右移6位与前者相或(|),获得第三个目标字符。//最后将第三个字符与0x3f(00111111)进行与(&)操作即获得第四个目标字符。//在以上的每一个步骤之后,再把结果与 0x3F 进行 AND 位操作,就可以得到编码后的字符了。原文的字节数量应该是3的倍数,如果这个条件不能满足的话,具体的解决办法是这样的:原文剩余的字节根据编码规则继续单独转(1变2,2变3;不够的位数用0补全),再用=号补满4个字节。这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为一个原字节至少会变成两个目标字节,所以余数任何情况下都只可能是0,1,2这三个数中的一个。如果余数是0的话,就表示原文字节数正好是3的倍数(最理想的情况)。如果是1的话,转成2个Base64编码字符,为了让Base64编码是4的倍数,就要补2个等号;同理,如果是2的话,就要补1个等号。
收起全文
精华内容
下载资源
问答
  • base64
    千次阅读
    2021-05-29 16:21:35

    一、jdk1.8下的 BASE64Encoder 和 BASE64Decoder(JDK9开始已移除):

    package com.lmp.utils;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    public class test {
        public static void main(String[] args) throws Exception {
    
            String str = "hello word";
            BASE64Encoder base64Encoder = new BASE64Encoder();
            // JDK1.8 BASE64Encoder 加密
            String encode = base64Encoder.encode(str.getBytes());
            System.out.println(encode);
    
            BASE64Decoder base64Decoder = new BASE64Decoder();
            // JDK1.8 BASE64Decoder 解密
            byte[] bytes = base64Decoder.decodeBuffer(encode);
            String res = new String(bytes);
            System.out.println(res);
    
        }
    
    }
    
    

    二、推荐使用Base64:

    package com.lmp.utils;
    
    import java.util.Base64;
    
    public class test {
        public static void main(String[] args) throws Exception {
    
            String str = "hello word";
            // JDK1.8 Base64加密
            String encode = Base64.getEncoder().encodeToString(str.getBytes());
            System.out.println(encode);
    
            // JDK1.8 Base64解密
            byte[] bytes = Base64.getDecoder().decode(encode);
            String res = new String(bytes);
            System.out.println(res);
        }
    
    }
    
    

    参考: JDK从1.8升级到9.0.1后sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用.

    更多相关内容
  • js的base64base64.js)

    2017-06-01 15:47:31
    js的base64base64.js)
  • base64.js文件是前段插件很好的运用js技术
  • base64encoder jar包

    2018-02-12 10:36:08
    java base64encoder jar包 可用MD5加密。亲测可用。。
  • Base64 是网络上最常见的用于传输8Bit 字节代码的编码方式之一
  • Java8新特性-Base64

    千次阅读 多人点赞 2021-02-13 00:51:58
    文章目录Base64 编码由来什么是 Base64Base64 的使用场景什么是 Base64Base64 的使用场景Base64 编码原理Base64 编码过程Base64 解码原理Base64 编码字符串实例Base64 具体实现对字符串进行 Base64 编解码...

    Base64 编码由来

    为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种基于64个可打印字符来表示二进制数据的表示方法。

    什么是 Base64 和 Base64 的使用场景

    什么是 Base64

    Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。由于 2⁶ = 64 ,所以每 6 个比特为一个单元,对应某个可打印字符。3 个字节有 24 个比特,对应于 4 个 base64 单元,即 3 个字节可由 4 个可打印字符来表示。相应的转换过程如下图所示:

    base64-convert

    Base64 的使用场景

    Base64 常用于在处理文本数据的场合,表示、传输、存储一些二进制数据,包括 MIME 的电子邮件及 XML 的一些复杂数据。在 MIME 格式的电子邮件中,base64 可以用来将二进制的字节序列数据编码成 ASCII 字符序列构成的文本。使用时,在传输编码方式中指定 base64。使用的字符包括大小写拉丁字母各 26 个、数字 10 个、加号 + 和斜杠 /,共 64 个字符,等号 = 用来作为后缀用途。Base64 相应的索引表如下:

    base64-encode-table

    Base64 编码原理

    看一下Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符。数值代表字符的索引,这个是标准Base64协议规定的,不能更改。64个字符用6个bit位就可以全部表示,一个字节有8个bit位,剩下两个bit就浪费掉了,这样就不得不牺牲一部分空间了。这里需要弄明白的就是一个Base64字符是8个bit,但是有效部分只有右边的6个bit,左边两个永远是0。

    那么怎么用6个有效bit来表示传统字符的8个bit呢?8和6的最小公倍数是24,也就是说3个传统字节可以由4个Base64字符来表示,保证有效位数是一样的,这样就多了1/3的字节数来弥补Base64只有6个有效bit的不足。

    Base64 编码过程

    1. 按照从左往右的规则,每三个字节作为一组,一共就是24个二进制位。
    2. 将这24个二进制位分为四组,每组6个二进制位。
    3. 之后在每组数据前面添加00,组成每个组8个二进制位,此时变成了32个二进制位,即四个字节
    4. 四个字节在Base64 索引表查找得到的对应符号,base64编码完成

    Base64 解码原理

    解码原理是将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。

    Base64 编码字符串实例

    了解了 Base64 编码原理,我们以编码 Man 字符串为例,来直观的感受一下编码过程。Man 由 M、a 和 n 3 个字符组成,它们对应的 ASCII 码为 77、97 和 110。

    char-m-ascii

    接着我们以每 6 个比特为一个单元,进行 base64 编码操作,具体如下图所示:

    base64-encode-demo

    由图可知,Man (3字节)编码的结果为 TWFu(4字节),很明显经过 base64 编码后体积会增加 1/3。Man 这个字符串的长度刚好是 3,我们可以用 4 个 base64 单元来表示。但如果待编码的字符串长度不是 3 的整数倍时,应该如何处理呢?

    如果要编码的字节数不能被 3 整除,最后会多出 1 个或 2 个字节,那么可以使用下面的方法进行处理:先使用 0 字节值在末尾补足,使其能够被 3 整除,然后再进行 base64 的编码

    以编码字符 A 为例,其所占的字节数为 1,不能被 3 整除,需要补 2 个字节,具体如下图所示:

    base64-encode-a

    由上图可知,字符 A 经过 base64 编码后的结果是 QQ==,该结果后面的两个 = 代表补足的字节数。而最后个 1 个 base64 字节块有 4 位是 0 值。

    接着我们来看另一个示例,假设需编码的字符串为 BC,其所占字节数为 2,不能被 3 整除,需要补 1 个字节,具体如下图所示:

    base64-encode-bc

    由上图可知,字符串 BC 经过 base64 编码后的结果是 QkM=,该结果后面的 1 个 = 代表补足的字节数。而最后个 1 个 base64 字节块有 2 位是 0 值。

    Base64 具体实现

    对字符串进行 Base64 编解码

    Encoder方式

    @Test
    public void testEncoder() {
        String str = "thinkwon";
        // 使用基本编码
        String base64encodedString = Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        System.out.println("Base64 编码字符串 (基本) :" + base64encodedString);
    
        // 解码
        byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
        System.out.println("原始字符串: " + new String(base64decodedBytes, StandardCharsets.UTF_8));
    }
    

    输出结果

    Base64 编码字符串 (基本) :dGhpbmt3b24=
    原始字符串: thinkwon
    

    UrlEncoder方式

    @Test
    public void testUrlEncoder() {
        String str = "thinkwon";
        // 使用基本编码
        String base64encodedString = Base64.getUrlEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        System.out.println("Base64 编码字符串 (URL) :" + base64encodedString);
    
        // 解码
        byte[] base64decodedBytes = Base64.getUrlDecoder().decode(base64encodedString);
        System.out.println("原始字符串: " + new String(base64decodedBytes, StandardCharsets.UTF_8));
    }
    

    输出结果

    Base64 编码字符串 (URL) :dGhpbmt3b24=
    原始字符串: thinkwon
    

    MimeEncoder方式

    @Test
    public void testMimeEncoder() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 2; ++i) {
            stringBuilder.append(UUID.randomUUID().toString());
        }
        System.out.println("原始字符串: " + stringBuilder.toString());
    
        byte[] mimeBytes = stringBuilder.toString().getBytes(StandardCharsets.UTF_8);
        String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
        System.out.println("Base64 编码字符串 (MIME) :");
        System.out.println(mimeEncodedString);
    
        byte[] decode = Base64.getMimeDecoder().decode(mimeEncodedString);
        System.out.println("解码字符串: " + new String(decode, StandardCharsets.UTF_8));
    }
    

    输出结果

    原始字符串: fb51e7aa-2303-4ffc-be8c-44de37b1417e783f2921-1a68-462e-a5e1-32d1ad6cc51a
    Base64 编码字符串 (MIME) :
    ZmI1MWU3YWEtMjMwMy00ZmZjLWJlOGMtNDRkZTM3YjE0MTdlNzgzZjI5MjEtMWE2OC00NjJlLWE1
    ZTEtMzJkMWFkNmNjNTFh
    解码字符串: fb51e7aa-2303-4ffc-be8c-44de37b1417e783f2921-1a68-462e-a5e1-32d1ad6cc51a
    

    对文件进行 Base64 编解码

    文件与 Base64 字符串转换工具类

    /**
     * 文件转化成base64字符串
     *
     * @param path 文件路径
     * @return String base64字符串
     */
    public static String fileToBase64Str(String path) {
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(new File(path));
            data = new byte[in.available()];
            in.read(data);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 对字节数组Base64编码
        return Base64.getMimeEncoder().encodeToString(data);
    }
    
    /**
     * 将base64字符串转换为文件并存储到指定位置
     *
     * @param base64Str base64字符串
     * @param filePath  文件路径
     * @return boolean true表示转换成功,false表示转换失败
     */
    public static boolean base64StrToFile(String base64Str, String filePath) {
        if (base64Str == null && filePath == null) {
            return false;
        }
        try {
            Files.write(Paths.get(filePath), Base64.getMimeDecoder().decode(base64Str), StandardOpenOption.CREATE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
    

    文件转 Base64 字符串

    @Test
    public void testFileToBase64() {
        String base64 = fileToBase64Str("C:\\Users\\JourWon\\Desktop\\优秀.jpg");
        System.out.println(base64);
    }
    

    输出结果

    /9j/4AAQSkZJRgABAQAAAQABAAD/4S/vRXhpZgAATU0AKgAAAAgABgESAAMAAAABAAEAAAEaAAUA后面还有很长的字符串...
    

    Base64 字符串转文件

    @Test
    public void testBase64ToFile() {
        boolean b = base64StrToFile("/9j/4AAQSkZJRgABAQAAAQABAAD/4S/vRXhpZgAATU0AKgAAAAgABgESAAMAAAABAAEAAAEaAAUA后面还有很长的字符串...", "C:\\Users\\JourWon\\Desktop\\base64转图片.jpg");
        System.out.println(b);
    }
    

    转换过程中可能存在的问题:

    1.运行出现错误为:“常量字符串过长”

    File >> Settings >> Build,Execution,Deployment >> Compiler >>Java Compiler,将 Use compiler 改为 Eclipse 即可
    

    2.运行出现错误为:java.lang.IllegalArgumentException: Illegal base64 character a

    注意base64StrToFile方法的decoder是Base64.getMimeDecoder(),不是Base64.getDecoder()
    

    输出结果

    在这里插入图片描述

    展开全文
  • Java 从网络中读取图片 转换成Base64字符串
  • Base64编码

    千次阅读 2021-12-16 11:28:24
    Base64是一种用64个字符来表示任意二进制数据的方法。它是一种编码方式,而非加密方式。它通过将二进制数据转变为64个“可打印字符”,完成了数据在HTTP协议上的传输。

    基本概念

    Base64这个术语最初是在“MIME内容传输编码规范”中提出的。Base64不是一种加密算法,虽然编码后的字符串看起来有点加密的赶脚。它实际上是一种“二进制到文本”的编码方法,它能够将给定的任意二进制数据转换(映射)为ASCII字符串的形式,以便在只支持文本的环境中也能够顺利地传输二进制数据。例如支持MIME的电子邮件应用,或需要在XML中存储复杂数据(例如图片)时。

    Base64是一种用64个字符来表示任意二进制数据的方法。它是一种编码方式,而非加密方式。它通过将二进制数据转变为64个“可打印字符”,完成了数据在HTTP协议上的传输。

    什么情况下我们会用到Base64呢?Base64一般用于在HTTP协议下传输二进制数据,由于HTTP协议是超文本协议,所以在HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的。因为网络传输只能传输可打印字符。

    什么是可打印字符?在ASCII码中规定,0-31、127这33个字符属于控制字符,32-126这95个字符属于可打印字符(具体对照关系可参见 ASCII码对照表),也就是说网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么该怎么才能传输其他字符呢?其中一种方式就是使用Base64。

    Base64,就是使用64个可打印字符来表示二进制数据的方法。这64个字符中包括大小写字母、数字、+和/,还有用来补缺的特殊字符=。

    注意:由于base64编码用了8位字符来表示信息中的6个位,所以base64编码字符串大约比原始值扩大了33%。

    Base64编码表

    码值字符码值字符码值字符码值字符码值字符码值字符码值字符码值字符
    0A8I16Q24Y32g40o48w564
    1B9J17R25Z33h41p49x575
    2C10K18S26a34i42q50y586
    3D11L19T27b35j43r51z597
    4E12M20U28c36k44s520608
    5F13N21V29d37l45t531619
    6G14O22W30e38m46u54262+
    7H15P23X31f39n47v55363/

    也就是说,如果将索引转换为对应的二进制数据的话需要至多6个Bit。然而ASCII码需要8个Bit来表示,那么怎么使用6个Bit来表示8个Bit的数据呢?6个Bit当然不能存储8个Bit的数据,但是4×6个Bit可以存储3×8个Bit的数据啊!如下表所示:

     

    可以看到“Son”通过Base64编码转换成了“U29u”。这是刚刚好的情况,3个ASCII字符刚好转换成对应的4个Base64字符。但是,当需要转换的字符数不是3的倍数的情况下该怎么办呢?Base64规定,当需要转换的字符不是3的倍数时,一律采用补0的方式凑足3的倍数,具体如下表所示:

    在这里插入图片描述
    每6个Bit为一组,第一组转换后为字符“U”,第二组末尾补4个0转换后为字符“w”。剩下的使用“=”替代。即字符“S”通过Base64编码后为“Uw==”。这就是Base64的编码过程。

    如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

    这是字节的位总数不是6的倍数的情况,当剩下4位时,我们需要补2个=凑齐8的倍数;当剩下的是2位时,我们需要补齐1个 = 凑齐8的倍数。
    补全机制

     

    要实现Base64,首先需要选取适当的64个字符组成字符集。一条通用的原则是从某种常用字符集中选取64个可打印字符,这样就能避免在传输过程中丢失数据(不可打印字符在传输过程中可能会被当做特殊字符处理,从而导致丢失)。例如,MIME的Base64实现选用了大写字母、小写字母和0~9的数字作为前62个字符。其他实现通常会沿用MIME的这种方式,而仅仅在最后2个字符上有所不同,例如UTF-7编码。

    Base64完整示例

    下面这段文本:

    Man is distinguished, not only by his reason, but by this singular passion from

    other animals, which is a lust of the mind, that by a perseverance of delight

    in the continued and indefatigable generation of knowledge, exceeds the short

    vehemence of any carnal pleasure.

    通过MIME Base64进行转换后就成为:

    TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz

    IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg

    dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu

    dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo

    ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

    转换方法

    以例子开头的“Man”被转换为“TWFu”为例,我们来看看Base64基本的转换过程:

    1. M、a和n的ASCII编码分别为01001101、01100001和01101110,合并后得到一个24位的二进制串010011010110000101101110

    2. 按每6位一组将其分为4组:010011、010110、000101、101110

    3. 最后按对应关系从字符集中取出4个字符(即T、W、F、u)作为结果(本文后面列出了由MIME定义的字符集)。

    Base64的基本思想就是这么简单:它将每3个字节(24位)转换为4个字符。因为6位二进制数可以表示64个不同的数,因此只要确定了字符集(含64个字符),并为其中的每个字符确定一个唯一的编码,就可以通过正向与反向映射将二进制字节转换为Base64编码或反之。

    补零处理

    通过不断将每3个字节转换为4个Base64字符之后,最后可能会出现以下3种情况之一:

    1. 没有字节剩下

    2. 还剩下1个字节

    3. 还剩下2个字节

    1没什么好说的。后面的2和3该如何处理呢?

    遇到这种情况,就需要在剩下的字节后面补零,直到其位数能够被6整除(因为Base64是对每6位进行编码的)。假如还剩下1个字节,即8位,那么需要再补4个0使其成为12位,这样就可以分为2组了;如果剩下2个字节,即16位,那么只需要再补2个0(18位)就可以分成3组了。最后再用普通方法做映射即可。

    还原时,依次将每4个字符还原成3个字节,最后会出现3种情况之一:

    1. 没有字符剩下

    2. 还剩下2个字符

    3. 还剩下3个字符

    这3种情况与上面的3种情况一一对应,只要对补零的过程反过来处理,就可以原样还原了。

    填充

    我们经常会在Base64编码字符串中看到最后有“=”字符,这就是通过填充生成的。填充就是当出现编码时的情况2和3时,在后面补上“=”字符,使编码后的字符数为4的倍数。

    所以我们可以很容易地想到,情况2,即还剩下1个字节时,需要补2个“=”,因为此时最后一个字节编码为2个字符,补上2个“=”正好凑够4个。情况3同理,需要补1个“=”。

    填充不是必须的,因为无需填充也可以通过编码后的内容计算出缺失的字节。所以在一些实现中填充是必须的,有些却不是。一种必须使用填充的场合是当需要将多个Base64编码文件合并为一个文件的时候。

    引申话题:利用Base64加密解密

    虽然本文的开头就已经提到过,Base64不是一种加密算法,但实际上我们确实可以利用Base64来加密数据。

    我们都知道,加密就是将明文变为密文的过程。在这个过程中起关键作用的一是算法,二则是密钥。算法相当于制造工艺或加工过程,而密钥则是配方。制造工艺可以公开,但配方必须保密,否则人人都能生产云南白药了。

    容易想到,Base64的配方就是字符集。选用的字符集不同,甚至只是改变一下字符集中字符的顺序(编号),相同的加工过程就会生成不同的Base64编码。

    例如,如果不告诉你编码时使用的字符集,你能知道下面的编码对应的原文是什么吗?

    TWl+Im1DImR5sHR5r2tFqXN4pWQ8ImZ/tih/r2BZImJZImx5sChCpWlDrGY8ImJFtihyuSh
    Eqm1DInN5r2tFrmlCInhxsHN5rGYwp3J/rSh/tmx1syhxr219oWBDLihHqm1zqih5sChxImB
    FsHQwrGowtmx1ImF5r2Q8InR4oXQwo30woShApXJDpXp1s2l+oGUwrGowpmV8qWt4t
    ih5ryhEqmUwoGd+tm1+tWV0Iml+pih5r2R1p2lEqWtxo2B1Imt1r2VCoXR5rGYwrGowqGZ
    /tGB1pmt1Lih1umN1pWRDInR4pShDqmdCtihGpWx1rWV+oGUwrGowoWZZImNxs2Zxrih
    ArmVxsHVCpSY=

    既然利用Base64来加密和解密是完全可行的,为什么又说它不是一种加密算法呢?

    这是因为:

    1. 开发Base64的目的就不是为了加密,而是为了方便在文本环境中传输二进制数据

    2. 所以,与开发一个加密算法不同,安全性并不是Base64的目标,只是它的一个副产物。

    实际上,Base64的安全性是非常差的,这就是在实际应用中不用它加密的原因。如果你对常用加密方法有所了解的话,你应该知道有一种古老的加密方法,称为“字符替换法”。即指定一个规则,将每个字符用其他字符替换,例如将a变为c、b变为d等,这样替换后生成的结果就是密文。解密时只需要反过来操作,将c变为a、将d变为b就可以了。用不同的替换规则加密,生成的密文也不同。

    用Base64来加密实际上就相当于字符替换,只不过它先对字节做了一些变换,然后再进行替换,对加密过程来说,本质上是一样的。

    Base64用法
    Java已经替我们写好Base64的实现细节,使用的时候直接调用即可。具体代码如下所示:

    package com.first;
     
    import org.junit.Test;
     
    import java.io.UnsupportedEncodingException;
    import java.util.Base64;
     
    public class Test {
     
        @Test
        public void test() throws UnsupportedEncodingException {
            // 编码
            String encode = Base64.getEncoder().encodeToString("So".getBytes("UTF-8"));
            System.out.println(encode);
            // 解码
            byte[] decode = Base64.getDecoder().decode(encode);
            System.out.println(new String(decode, "UTF-8"));
        }
    }

    Base64的特点
    1、首先这算法是编码,不是压缩,编码后只会增加字节数;字节数会成为原字节数的4/3;
    2、算法简单, 几乎不会影响效率;
    3、算法可逆, 解码很方便, 不用于私密信息通信;
    4、虽然解码方便, 但毕竟编码了, 肉眼还是不能直接看出原始内容;
    5、加密后的字符串只有[0-9a-zA-Z+/=],不可打印字符(包括转移字符)也可传输;
     

    展开全文
  • android.util.Base64

    热门讨论 2015-07-26 13:25:47
    android.util.Base64
  • Java实现Base64的编码与解码

    千次阅读 2022-01-07 18:31:40
    什么是Base64Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。3个字节相当于24个比特,对应于4个Base64单元,即3个...

    什么是Base64?

    Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。3个字节相当于24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。在Base64中的可打印字符包括字母A-Za-z数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后BinHex的版本使用不同的64字符集来代表6个二进制数字,但是不被称为Base64。

    Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME电子邮件XML的一些复杂数据。

    关于Base64我们要明白的最重要的一点就是,他是一中编码格式,而不是加密算法

    Base64编码索引表:

     

    为什么会有Base64这个东西出现?

    Base64的出现是为了让一些二进制数据可视化并且能够进行传输,存储。例如图片、音频、视频等。

    Base64 会经常用作一个简单的“加密”来保护某些数据,而真正的加密通常都比较繁琐。

    规则:

    Base64将3个字节变成4个字节。

    如果要编码的字节数不能被3整除,最后会多出1个或2个字节,那么可以使用下面的方法进行处理:先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。也就是说,当最后剩余两个八位(待补足)字节(2个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;如果最后剩余一个八位(待补足)字节(1个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。

    下面我们用Java实现Base64算法:

    首先我们要将Base64的对照表存进一个char型数组中去,为了之后要用的时候可以直接查表打印。

    public static char[] base64 = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K','L', 'M', 'N','O', 'P',
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f','g', 
    'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 
    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
    };

    以下是编码的代码:


    private static List<String> encodeToBase64(byte[] bytes) {
    ​
        //记录编码的字节数被3除的余数
            int num = bytes.length % 3;
    ​
            List<String> stringList = new ArrayList<String>();
            int v = 0;
            for (int i = 2; i < bytes.length; i += 3) {
                //用V来接收拼接后的数,由于byte数组中每一个是8位的二进制数,三个拼起来正好是24位
                v = ((bytes[i - 2] & 0xff) << 16) | ((bytes[i - 1] & 0xff) << 8) | (bytes[i] & 0xff);
                //在将v与0x3f进行&运算,每次取到六位,将其分成4组
                //与0x3f进行&运算,是因为0x3f的二进制码是0011 1111,中间包含六个1,只有在全一的时候才会为1,所以值取到了最后六位
                int d0 = v & 0x3f;
                int d1 = v >>> 6 & 0x3f;//>>>为无符号的位运算
                int d2 = v >>> 12 & 0x3f;
                int d3 = v >>> 18 & 0x3f;
    ​
                //将取得的4组6位数据查表后存入List中
                stringList.add(String.valueOf(base64[d3]));
                stringList.add(String.valueOf(base64[d2]));
                stringList.add(String.valueOf(base64[d1]));
                stringList.add(String.valueOf(base64[d0]));
    ​
            }
        //下面的操作是当编码的字节数不能被3整除时,在末尾添加等于号
            if (num > 1) {
                v = ((bytes[bytes.length - 2] & 0xff) << 16) | ((bytes[bytes.length - 1] & 0xff) << 8);
    ​
                int d1 = v >>> 6 & 0x3f;
                int d2 = v >>> 12 & 0x3f;
                int d3 = v >>> 18 & 0x3f;
                stringList.add(String.valueOf(base64[d3]));
                stringList.add(String.valueOf(base64[d2]));
                stringList.add(String.valueOf(base64[d1]));
                stringList.add("=");
            }
            if (num == 1) {
                v = ((bytes[bytes.length - 1] & 0xff) << 16);
    ​
                int d2 = v >>> 12 & 0x3f;
                int d3 = v >>> 18 & 0x3f;
                stringList.add(String.valueOf(base64[d3]));
                stringList.add(String.valueOf(base64[d2]));
                stringList.add("=");
                stringList.add("=");
            }
        //输出编码后结果
            System.out.print("Base64 编码后:");
            for (String s : stringList) {
                System.out.print(s);
            }
            System.out.println();
            return stringList;
        }

    相对编码来说,解码会更加简单些,代码如下:

    private static void decode(String string) {
    ​
            byte[] b = new byte[string.length()];
            char[] ch = string.toCharArray();
            int n = 0;
        //遍历Base64表获取下标并存入byte数组
            for (char c : ch) {
                for (int i = 0; i < base64.length; i++) {
                    if (c == base64[i]) {
                        b[n] = (byte) i;
                        n++;
                    }
                }
            }
    ​
            int v = 0;
            byte[] bytes = new byte[string.length() - 1];
            int num = 0;
        //将4组合并,并且分为3组每组8位
            for (int i = 0; i < b.length; i += 4) {
                v = ((b[i] & 0xff) << 18) | ((b[i + 1] & 0xff) << 12) | (b[i + 2] & 0xff) << 6 | (b[i + 3] & 0xff);
    ​
                int d0 = v & 0xff;
                int d1 = v >>> 8 & 0xff;
                int d2 = v >>> 16 & 0xff;
    ​
                bytes[num] = (byte) d2;
                bytes[num + 1] = (byte) d1;
                bytes[num + 2] = (byte) d0;
                num += 3;
    ​
            }
    //去除byte数组末尾的0,末尾有0才去除
            if (bytes[bytes.length - 1] == 0){
                try {
                    int length = 0;
                    for (int i = 0; i < bytes.length; ++i) {
                        if (bytes[i] == 0) {
                            length = i;
                            break;
                        }
                    }
                    String str1 = new String(bytes,0,length);
                    System.out.println("字符串 "+string+" Base64 解码后:"+str1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else{
    ​
            String s1 = new String(bytes);
            System.out.println("字符串 "+string+" Base64 解码后:"+s1);
            }
        }

    最后我们只要调用方法就好了。

    测试用例:

    原始字符串:丢

    Base64 编码后:5Lii

    再用 Base64 解码后:丢

    原始字符串:丢15as

    Base64 编码后:5LiiMTVhcw==

    再用 Base64 解码后:丢15as

    想了解更详细的介绍可以点击链接:Base64

    如果有不明白的地方也可以私信我哦~

    展开全文
  • 说明: (1)为什么写这篇博客?...】→【然后,因为以前遇到过多次使用Base64转码的情况】→【所以,意识到了【好好总结下Base64转码】的必要性】;所以写了本篇博客; 目录 一:以前遇到过的【使..
  • Base64码常见操作(url链接文件转base64编码、本地文件转base64编码等)
  • BASE64源码及JAR包

    千次下载 热门讨论 2015-02-11 10:49:39
    sun.misc.BASE64Encoder 的源码及JAR包
  • Base64加密解密java/js

    热门讨论 2013-02-01 16:17:20
    参照网上Base64 js加密解密写的java实现,网上没看到出现过,可能大神都不屑写这种小东东,只好自己写了。弄了好几天,总算弄好了。 因为是参照 js Base64写的java实现,所以代码可实现前台js,后台java的加密,...
  • BASE64编码解码

    千次阅读 2021-08-25 11:28:14
    1 Base64编码概述 Base64是一种编码方式,这个术语最初是在“MIME内容传输编码规范”中提出的。Base64不是一种加密算法,它实际上是一种“二进制转换到文本”的编码方式,它能够将任意二进制数据转换为ASCII字符串...
  • Base64编码详解与URL安全的Base64编码

    千次阅读 2021-07-23 18:10:18
    Base64的基本编码方式 base64编码是一种常见的编码方式,主要用于对8bit的字节进行编码。具体的编码方式是: 把三个字节作为一组,转化为二进制的形式,一共3*8=24个二进制位。 例如: abc 三个字符用ASCII编码,...
  • base64加密及方式

    千次阅读 2021-11-29 18:30:14
    base64编码 出于数据加密的目的或者网络协议的限制或者特殊字符的处理等,通常需要将原文转换为base64编码,比如:发送某些含有 ASCII 码表中 0 到 31 之间的控制字符的数据。 常见转换方式 1.使用window.btoa() ...
  • 自学Android开发 Java和Android SDK的Base64

    千次阅读 2022-03-29 23:30:22
    在Android开发使用AES加密时,会发现Android SDK自带了Base64,但是它加密的结果和Java JDK的Base64 不一致,所以造成了Java 服务后端的加密数据,用SDK的Base64无法解密,造成了异常。后来Android 开发也引入了Java...
  • base64转图片+图片转base64

    万次阅读 2021-05-20 14:50:22
    【工具类篇·base64转图片·图片转base64
  • php中base64_decode与base64_encode加密解密函数,实例分析了base64加密解密函数的具体用法,具有一定的实用价值,需要的朋友可以参考下本文实例讲述了php中base64_decode与base64_encode加密解密函数。分享给大家供...
  • iOS Base64URL编码:java中,在进行base64编码时会看到相似如下代码:String result = Base64.encodeToString(bytedata, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);其中参数的含义是:URL_SAFE:...
  • C#Base64简单加密与解密

    千次阅读 2021-11-29 22:14:56
    Base64属于简单加密算法的一种。类似于凯撒密码【它是一种替换加密的技术】 Base64字符串由65个字符组成, 大写字母A~Z, 小写字母a~z, 数字0~9,以及三个特殊字符+、/、= 【=“等号”用于补充字符,使Base64字符...
  • 1、前言书接上回,上次是经过返回base64码给前端页面,实现了咱们访问项目外图片的目的。只是代码实在是太长了,很差看啊,得想办法优化下。顺带了解下base64究竟是啥,用着好很差,会不会影响速度呢?php2、代码...
  • jquery.base64.js

    千次下载 热门讨论 2014-05-22 14:06:04
    jquery.base64.js
  • Base64以及关于Base64遇到的坑

    千次阅读 2020-05-13 13:35:37
    使用Base64 public String encode(String src) { byte[] encodeBytes = Base64.getEncoder().encode(src.getBytes()); return new String(encodeBytes); } public String decode(String src) { byte[] ...
  • 在实现了将文件通过Base64的方式加密存储到数据库中并且读取到相应的文件时,在通过Base64的解密方法进行解密时,出现了不应该出现的错误,将解决问题的过程在这里进行记录和总结 提示:以下是本篇文章正文内容,...
  • base64.jar

    千次下载 热门讨论 2013-01-16 14:04:40
    base64.jar
  • js实现base64编码,前端一般应用场景在与后端接口参数中体现,后端可能需要某个字段是base64编码的字符,这时候就需要用前端的方法进行转换,再作为参数传递到服务端。
  • js中base64编码

    千次阅读 2022-05-09 11:39:04
    1. 使用 Buffer对象 Buffer.from(JSON.stringify(jwtHeader)).... * base64js.byteLength(base64Str) base64字符串转为字节数组的长度 * base64js.toByteArray(base64Str) base64字符串转为字节数组 * base64js.fro
  • java base64的jar包

    千次下载 热门讨论 2013-07-30 22:47:43
    http://blog.csdn.net/yx0628/article/details/9633947 这个是gps转百度地图坐标的相关介绍。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 789,864
精华内容 315,945
关键字:

base64

友情链接: ajax_init.rar