热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于javascript:前端的base64-转换实现

window.btoa和window.atob,是浏览器提供的字符串base64编解码。然而该办法不反对中文字符串的转码。因为转码是针对ASCII码。

window.btoa和window.atob,是浏览器提供的字符串base64编解码。
然而该办法不反对中文字符串的转码。因为转码是针对ASCII码。

能够如下操作实现

window.btoa(window.encodeURIComponent(str))
window.decodeURIComponent(window.atob(str))

先将中文编码,而后再转base64

留神

无论是escape,encodeURIComponent,encodeURI那种办法,都不是专门针对中文的。
所以,以上办法也会将一些特殊符号@*/+等转码
后果就是除了中文以外的其余字符最终后果和间接btoa的后果不统一。

这里就要看应用场景,只是前端应用没有问题,如果波及到后盾等第三方就不能用了。
罕用的js-base插件办法:encode,
原理如下

  • 将字符串中非acsill字符按固定规定转为两个或者三个长度的UTF-16码

    • 要害就是这段代码
    const cb_utob = (c) => {
       if (c.length <2) {
           var cc = c.charCodeAt(0);
           return cc <0x80 ? c
               : cc <0x800 ? (_fromCC(0xc0 | (cc >>> 6))
                   + _fromCC(0x80 | (cc & 0x3f)))
                   : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))
                       + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                       + _fromCC(0x80 | (cc & 0x3f)));
       }
       else {
           var cc = 0x10000
               + (c.charCodeAt(0) - 0xD800) * 0x400
               + (c.charCodeAt(1) - 0xDC00);
           return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))
               + _fromCC(0x80 | ((cc >>> 12) & 0x3f))
               + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
               + _fromCC(0x80 | (cc & 0x3f)));
       }
    };
    const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
    //utf-8 string return utf-16字符串
    const utob = (u) => u.replace(re_utob, cb_utob);
  • 而后就能够转base64了
const btoaPolyfill = (bin) => {
   // console.log('polyfilled');
   let u32, c0, c1, c2, asc = '';
   const pad = bin.length % 3;
   for (let i = 0; i  255 ||
           (c1 = bin.charCodeAt(i++)) > 255 ||
           (c2 = bin.charCodeAt(i++)) > 255)
           throw new TypeError('invalid character found');
       u32 = (c0 <<16) | (c1 <<8) | c2;
       asc += b64chs[u32 >> 18 & 63]
           + b64chs[u32 >> 12 & 63]
           + b64chs[u32 >> 6 & 63]
           + b64chs[u32 & 63];
   }
   return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
};
  • 这个办法是插件本人的转base64办法,每个base64字符代表3个bit,办法其实我没太看懂

mdn还有另一种办法

  • 原理字符串间接映射ArrayBuffer二进制数组

代码和地址如下:

  /* Array of bytes to base64 string decoding */

function b64ToUint6 (nChr) {

  return nChr > 64 && nChr <91 ?
      nChr - 65
    : nChr > 96 && nChr <123 ?
      nChr - 71
    : nChr > 47 && nChr <58 ?
      nChr + 4
    : nChr === 43 ?
      62
    : nChr === 47 ?
      63
    :
      0;

}

function base64DecToArr (sBase64, nBlockSize) {

  var
    sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
    nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen);

  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx >> (16 >>> nMod3 & 24) & 255;
      }
      nUint24 = 0;
    }
  }

  return aBytes;
}

/* Base64 string to array encoding */

function uint6ToB64 (nUint6) {

  return nUint6 <26 ?
      nUint6 + 65
    : nUint6 <52 ?
      nUint6 + 71
    : nUint6 <62 ?
      nUint6 - 4
    : nUint6 === 62 ?
      43
    : nUint6 === 63 ?
      47
    :
      65;

}

function base64EncArr (aBytes) {

  var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = "";

  for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx  0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
    */
    nUint24 |= aBytes[nIdx] <<(16 >>> nMod3 & 24);
    if (nMod3 === 2 || aBytes.length - nIdx === 1) {
      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
      nUint24 = 0;
    }
  }

  return  eqLen === 0 ?
      sB64Enc
    :
      sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");

}

MDN-base64


推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • C语言常量与变量的深入理解及其影响
    本文深入讲解了C语言中常量与变量的概念及其深入实质,强调了对常量和变量的理解对于学习指针等后续内容的重要性。详细介绍了常量的分类和特点,以及变量的定义和分类。同时指出了常量和变量在程序中的作用及其对内存空间的影响,类似于const关键字的只读属性。此外,还提及了常量和变量在实际应用中可能出现的问题,如段错误和野指针。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
author-avatar
q40796672
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有