当前位置: 首页 > news >正文

网站的友情链接做多少个比较合适/百度免费推广网站

网站的友情链接做多少个比较合适,百度免费推广网站,网站 多线,中国铁路建设投资公司官方网站Base64由来: Base64算法最早应用于解决电子邮件传输的问题。在早期,由于“历史问题”,电子邮件只允许ASCII码字符。如果要传输一封带有非ASCII码字符的电子邮件,当通过有“历史问题”的网关时就可能出现问题。这个网关很可能会对这…

  Base64由来:

  Base64算法最早应用于解决电子邮件传输的问题。在早期,由于“历史问题”,电子邮件只允许ASCII码字符。如果要传输一封带有非ASCII码字符的电子邮件,当通过有“历史问题”的网关时就可能出现问题。这个网关很可能会对这个非ASCII码字符的二进制位做调整,即将这个非ASCII码的8位二进制码的最高位置为0。此时用户收到的邮件就会是一封纯粹的乱码邮件。基于这个原因产生了Base64算法。

  Base64定义:

  根据RFC2045、RFC4648规定,Base64由64个ASCII码字符组成,Base64目前有三种格式,RFC2045、RFC4648、RFC4648 URLSAFE。

  RFC2045、RFC4648、RFC4648 URLSAFE区别:

  · RFC2045和RFC4648中所用字符如表1,RFC2045规定,每76个字符为一行,每行末需添加一个回车换行符(\r\n)。

  · RFC4648 URLSAFE中所用字符如表2,与RFC2045、RFC4648有两个字符不一样,+、/由-、替换,由于+和/在URL编码时,会出现丢失,所以提供了替换更为安全的-、

ValueEncodingValueEncodingValueEncodingValueEncoding
0A17R34i51z
1B18S35j520
2C19T36k531
3D20U37l542
4E21V38m553
5F22W39n564
6G23X40o575
7H24Y41p586
8I25Z42q597
9J26a43r608
10K27b44s619
11L28c45t62+
12M29d46u63/
13N30e47vpadding=
14O31f48w
15P32g49x
16Q33h50y

                        表 1

ValueEncodingValueEncodingValueEncodingValueEncoding
0A17R34i51z
1B18S35j520
2C19T36k531
3D20U37l542
4E21V38m553
5F22W39n564
6G23X40o575
7H24Y41p586
8I25Z42q597
9J26a43r608
10K27b44s619
11L28c45t62-
12M29d46u63_
13N30e47vpadding=
14O31f48w
15P32g49x
16Q33h50y

                       表 2

  演示示例:

  JDK1.8版本开始,JDK默认提供Base64工具类,即java.util.Base64,其中对RFC2045、RFC4648、RFC4648 URLSAFE格式加解码,示例如下:

package com.securitit.serialize.bs64;import java.util.Base64;public class Base64Tester {public static void main(String[] args) throws Exception {String plainStr = null;String bs64Str = null;byte[] plainBts = null;// 原文内容.plainStr = "Hello Base64!Now this is testing RFC2045 Base64!Please see the result!";// RFC2045测试.bs64Str = Base64.getMimeEncoder().encodeToString(plainStr.getBytes("UTF-8"));System.out.println("RFC2045-Base64编码结果:");System.out.println(bs64Str);plainBts = Base64.getMimeDecoder().decode(bs64Str);plainStr = new String(plainBts, "UTF-8");System.out.println("RFC2045-Base64解码结果:");System.out.println(plainStr);System.out.println("===============================================================");// RFC4648测试.bs64Str = Base64.getEncoder().encodeToString(plainStr.getBytes("UTF-8"));System.out.println("RFC4648-Base64编码结果:");System.out.println(bs64Str);plainBts = Base64.getDecoder().decode(bs64Str);plainStr = new String(plainBts, "UTF-8");System.out.println("RFC4648-Base64解码结果:");System.out.println(plainStr);System.out.println("===============================================================");// RFC4648 URLSAFE测试.bs64Str = Base64.getUrlEncoder().encodeToString(plainStr.getBytes("UTF-8"));System.out.println("RFC4648 URLSAFE-Base64编码结果:");System.out.println(bs64Str);plainBts = Base64.getUrlDecoder().decode(bs64Str);plainStr = new String(plainBts, "UTF-8");System.out.println("RFC4648 URLSAFE-Base64解码结果:");System.out.println(plainStr);}}

  输出结果:

RFC2045-Base64编码结果:
SGVsbG8gQmFzZTY077yBTm93IHRoaXMgaXMgdGVzdGluZyBSRkMyMDQ1IEJhc2U2NO+8gVBsZWFz
ZSBzZWUgdGhlIHJlc3VsdO+8gQ==
RFC2045-Base64解码结果:
Hello Base64!Now this is testing RFC2045 Base64!Please see the result!
===============================================================
RFC4648-Base64编码结果:
SGVsbG8gQmFzZTY077yBTm93IHRoaXMgaXMgdGVzdGluZyBSRkMyMDQ1IEJhc2U2NO+8gVBsZWFzZSBzZWUgdGhlIHJlc3VsdO+8gQ==
RFC4648-Base64解码结果:
Hello Base64!Now this is testing RFC2045 Base64!Please see the result!
===============================================================
RFC4648 URLSAFE-Base64编码结果:
SGVsbG8gQmFzZTY077yBTm93IHRoaXMgaXMgdGVzdGluZyBSRkMyMDQ1IEJhc2U2NO-8gVBsZWFzZSBzZWUgdGhlIHJlc3VsdO-8gQ==
RFC4648 URLSAFE-Base64解码结果:
Hello Base64!Now this is testing RFC2045 Base64!Please see the result!

  从输出可以很明显的看出各种格式的区别,每种数据格式都对应某种应用场景。RFC2045较合适邮件传输,RFC4648较适合针对文件、大数据的编码,RFC4648 URLSAFE较适合需要在URL中传输的数据。

  源码分析:

  Base64编码是将3个字节转换为4个字节,然后使用ASCII表示,大致过程如下图所示:

在这里插入图片描述

  当3个字节转换为二进制后变为24位二进制,这24位二进制均分后变为4个字节,每个字节只有低6位是有效的,低6位的值范围是0-63,正好是本文开头的字典数据。

  接下来,我们以JDK1.8的java.util.Base64为例,对源码进行简单分析。

  实现基础:

  实现基础就是本文开头两个字典,按照上图中的过程,转换后按照字典取值,拼接为字符串,即是Base64编码后的值。

  基本方法:

  java.util.Base64的源码相对比较简单,我们只对其中两个比较重要的方法encode0和decode0进行分析,这两个方法是编码和解码的主要方法,其他方法都是围绕这两个方法进行的简单封装和调用,在此不做赘述。

  encode0:

  encode0方法负责编码。

private int encode0(byte[] src, int off, int end, byte[] dst) {// 取得编码字典.char[] base64 = isURL ? toBase64URL : toBase64;// 源数据初始位置.int sp = off;// 对字节数组进行分组,三个字节为一组,计算可分组数量.int slen = (end - off) / 3 * 3;// 可完整的分组的数量.int sl = off + slen;// 若限定每行最大字符数,且最大分组数大于每行最大字符数对应的最大分组数.if (linemax > 0 && slen  > linemax / 4 * 3)// 使用每行最大字符数计算最大分组数.slen = linemax / 4 * 3;int dp = 0;// 处理源数据,直到数据处理完为止.while (sp < sl) {// 若未处理完,则s10为当前处理为止.int sl0 = Math.min(sp + slen, sl);for (int sp0 = sp, dp0 = dp ; sp0 < sl0; ) {// 取3个字节的低8位,组成一个23位的int.int bits = (src[sp0++] & 0xff) << 16 |(src[sp0++] & 0xff) <<  8 |(src[sp0++] & 0xff);// 0x3f二进制是0011 1111// 下面四个语句,针对24位,每6位与0x3f进行&操作,结果作为一个字节.dst[dp0++] = (byte)base64[(bits >>> 18) & 0x3f];dst[dp0++] = (byte)base64[(bits >>> 12) & 0x3f];dst[dp0++] = (byte)base64[(bits >>> 6)  & 0x3f];dst[dp0++] = (byte)base64[bits & 0x3f];}// 一次处理过后,对数据进行初始化.int dlen = (sl0 - sp) / 3 * 4;dp += dlen;sp = sl0;// CRF2045协议处理.if (dlen == linemax && sp < end) {for (byte b : newline){dst[dp++] = b;}}}// 对剩余的未到3个的字节处理.if (sp < end) {               // 1 or 2 leftover bytesint b0 = src[sp++] & 0xff;dst[dp++] = (byte)base64[b0 >> 2];if (sp == end) {dst[dp++] = (byte)base64[(b0 << 4) & 0x3f];// 若需要补位,则用=进行补位.if (doPadding) {dst[dp++] = '=';dst[dp++] = '=';}} else {// 取数据低8位.int b1 = src[sp++] & 0xff;dst[dp++] = (byte)base64[(b0 << 4) & 0x3f | (b1 >> 4)];dst[dp++] = (byte)base64[(b1 << 2) & 0x3f];// 若需要补位,则用=进行补位.if (doPadding) {dst[dp++] = '=';}}}return dp;
}

  decode0:

  decode0方法负责解码。

private int decode0(byte[] src, int sp, int sl, byte[] dst) {// 是RFC4648或RFC4648 URLSAFE.int[] base64 = isURL ? fromBase64URL : fromBase64;int dp = 0;int bits = 0;// 处理4个字节时,首个字节移动位数.int shiftto = 18;// 遍历源数据,直至源数据遍历结束.while (sp < sl) {// 逐个获取字节低8位.int b = src[sp++] & 0xff;// 低8位在字典中数值小于0时.if ((b = base64[b]) < 0) {// 包含=的填充.if (b == -2) {// =     shiftto==18 unnecessary padding// x=    shiftto==12 a dangling single x// x     // xx=   shiftto==6&&sp==sl missing last =// xx=y  shiftto==6 last is not =// 输入字节数组有错误的4字节结束单元.// 移位数量为18时,没必要填充.// 移位数量为12时,只有一个值,例如:x=.// 与无填充示例一起使用.// 移位数量为6时,且源数据已到末尾,丢失最后的=,// 移位数量为6时,最后一个字符不是=.if (shiftto == 6 && (sp == sl || src[sp++] != '=') ||shiftto == 18) {throw new IllegalArgumentException("Input byte array has wrong 4-byte ending unit");}break;}// 跳过RFC2045.if (isMIME)    // skip if for rfc2045continue;// 其它情况进行异常处理.elsethrow new IllegalArgumentException("Illegal base64 character " +Integer.toString(src[sp - 1], 16));}// 拼接bits,将4个字节放一起.// 第一个字节左移18位.// 第二个字节左移12位.// 第三个字节左移6位.// 第四个字节不做移动.bits |= (b << shiftto);// 以6位差递减移位数量.shiftto -= 6;// 移位数量小于0时.if (shiftto < 0) {// 将拼接好的bits拆分为3个字节.dst[dp++] = (byte)(bits >> 16);dst[dp++] = (byte)(bits >>  8);dst[dp++] = (byte)(bits);// 恢复移位数量为18.shiftto = 18;// 4个字节拼接存储结果.bits = 0;}}// 当最后移位数量为6时,计算一个字节.if (shiftto == 6) {dst[dp++] = (byte)(bits >> 16);} else // 当最后移位数量为0时,计算两个字节.if (shiftto == 0) {dst[dp++] = (byte)(bits >> 16);dst[dp++] = (byte)(bits >>  8);} else // 当最后移位数量为12时,此时说明字节处理异常.    if (shiftto == 12) {// dangling single "x", incorrectly encoded.throw new IllegalArgumentException("Last unit does not have enough valid bits");}// 未处理到结尾.while (sp < sl) {// 当是媒体类型. && 源数据指定位置字节对应字典数据小于0时.if (isMIME && base64[src[sp++]] < 0)continue;throw new IllegalArgumentException("Input byte array has incorrect ending byte at " + sp);}return dp;
}

​  除了上面提供的方法,还提供了EncOutputStream、DecIInputSream用来针对流数据进行编码和解码,虽然接口和实现存在差异,但整体思路大致类似,各位若想知道具体原理,可查看源码详细分析。

  注:文中源码均来自于JDK1.8版本,不同版本间可能存在差异。

  如果有哪里有不明白或不清楚的内容,欢迎留言哦!

http://www.lbrq.cn/news/1250227.html

相关文章:

  • 家具网站建设策划书/seo搜索引擎优化到底是什么
  • 广东网站开发建设/电脑培训网
  • 贵阳网站建设制作方法/网络推广运营外包公司
  • 公司网站搜索引擎排名/2022年适合小学生的新闻
  • 广州做餐饮的招聘网站/做app推广去哪找商家
  • 柯桥做网站有哪些公司/注册推广赚钱一个80元
  • 兴义做网站的公司/微信加人推码35一单
  • 党建网站制作/汕头seo托管
  • 做web网站的步骤/如何做一个自己的网站呢
  • 做app和做网站/百度推广引流
  • 手机网站打开很慢/百度的网址是什么
  • dw做动态网站站点怎么/网站检测
  • 建设银行泰安培训中心官方网站/杭州seo泽成
  • 在网上做翻译的网站/网页关键词排名优化
  • 灵犀科技 高端网站建设首页/网站更新seo
  • 日本专线快递公司/包头整站优化
  • 深圳网站建设电话/seo网络科技有限公司
  • 个人网站建站源码/seo网站排名的软件
  • 织梦网站添加视频/自己开一个培训机构流程
  • wordpress ttfb/天津seo网站推广
  • 苏州相城网站建设/百度指数下载手机版
  • 重庆工业网站建设/北京网络营销公司
  • 网站建设业务活动/搜索指数查询
  • 网站后台jsp怎么做分页/下载百度网盘app最新版
  • 网站设计经典案例/推广方式营销方案
  • 云南企业网站建设有限公司/网络营销推广方案3篇
  • 阿里云虚拟主机建网站/软文推广文章范文1000
  • 骗子会利用钓鱼网站做啥/公司网站制作模板
  • 宁德市路桥建设有限公司网站/重庆放心seo整站优化
  • 建个网站要多少钱/哪里可以接广告
  • 专题:2025财务转型与AI赋能数字化报告|附30+份报告PDF汇总下载
  • 深度学习的视觉惯性里程计(VIO)算法优化实践
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的微商产品经营策略研究
  • 基于最大似然估计的卡尔曼滤波与自适应模糊PID控制的单片机实现
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘caffe’问题
  • Javascript/ES6+/Typescript重点内容篇——手撕(待总结)