关于base64编码解码(Android编码,JS解码,案例为解决安
卓端H5页⾯的emoj。。。
1、前⾔:
Base64是⽹络上最常⽤的⽤于传输8Bit字节代码的编码⽅式之⼀,⽐如开发中⽤于传递参数、现代浏览器中的<img />标签直接通过
Base64字符串来渲染图⽚,以及⽤于邮件中等等。Base64编码在RFC2045中定义为:Base64内容传送编码被设计⽤来把任意序列的8位字节描述为⼀种不易被⼈直接识别的形式。
2、应⽤举例:
以“迅雷下载”为例:很多下载类⽹站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专⽤下载地址。其实迅雷的“专⽤地址”也是⽤Base64“加密”的,其过程如下:
⼀、在地址的前后分别添加AA、ZZ
⼆、对新的字符串进⾏Base64编码
另:Flashget与迅雷类似,只不过在第⼀步时加的“料”不同,Flashget在地址前后加的“料”是[FLASHGET],⽽QQ旋风的没有加料,直接对地址进⾏Base64编码。
3、编码原理:
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前⾯补两个0,形成8位⼀个字节的形式。由于2的6次⽅为64,所以每6个位为⼀个单元,对应某个可打印字符。当原数据不是3的整数倍时,如果最后剩下两个输⼊数据,在编码结果后加1个“=”;如果最后剩下⼀个输⼊数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么也不要加,这样才能保证资料还原的正确性。
4、转码对照表:
5、解码原理:
解码是编码的逆过程,先看后⾯补了⼏个“=”,最多只可能补2个,⼀个“=”相当于补了2个0,所以去掉后⾯补的0后再按8位展开,即可还原。
6、不同语⾔采⽤Base64编解码区别:
除了语⾔上本质的区别外,因为字符编码是⼀样的,所以结果也⼀样。
也就是说后台不管你使⽤的是什么语⾔,你可以将编码后的数据传到前端使⽤JavaScript来解码。
7、实际项⽬遇到的问题:
描述:在Android中已经将评论中的表情包准备好,也能够存储到数据库中(这⾥⽤的是base64编码),⽬前表情⽆法在HTML5页⾯显⽰;
思路:1、将评论中的表情提取出来(即[mideo][/mideo]中的内容,这⾥需要注意的是提取出来的base64编码,然后⼀条评论中可能存在多个表情,也就是符合筛选条件的字符串可能有多个)
2、将base64解码为Unicode编码(这⾥分了多步解码)
3、取出对应的图⽚插⼊评论中
4、评论显⽰在前端页⾯
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>7⽉14⽇H5上的表情显⽰</title>
<script src="decode.js"></script>
<script src="emoji.js"></script>
</head>
<body>
<script>
//将表情从评论中提取出来,这⾥返回的是⼀个数组
var emojis = content.match(/(\[mideo\].*?\[\/mideo\])/g);
//分开处理每个表情
for (var i = 0; i < emojis.length; i++) {
var emojiStr = emojis[i];
//提取,将[mideo],[/mideo]去掉
var emojiItem = place('[mideo]', '');
emojiItem = place('[/mideo]', '');
//此处将base64编码解码为了utf8
var emojiCode = b64_to_utf8(emojiItem);
var emoji = new EmojiConvertor();
emoji.img_sets.mideo.path += 'emoji_';
//output为⼀个<img>标签,src即为相应的表情图⽚
var output = place_unified(emojiCode);
content = place(emojiStr,output);
}
</script>
</body>
</html>
//decode.js
function b64_to_utf8(str){
str = place(/\s/g,'');
return decodeURIComponent(escape(window.atob(str)));
}
//emoji.js
(function(){
var root = this;
var previous_emoji = root.EmojiConvertor;
var emoji = function(){
var emoji = function(){
var self = this;
/
/表情图像配置
self.img_set = 'mideo';
//可供选择的图⽚设置
self.img_sets = {
'mideo' : {'path' : '/page/img/emoji/'}
};
//图⽚格式,即插⼊表情的样式
self.use_css_imgs = false;
//colons_mode,text_mode 将表情符替换为适当的表⽰,替换为他们的冒号字符串表⽰ lons_mode = false;
<_mode = false;
//title属性
self.include_title = false;
//平台是否⽀持本地表情
self.allow_native = true;
//当平台⽀持时,使⽤精灵图代替单个图⽚
//防⽌本地⿊⽩windows表情被使⽤
self.avoid_ms_emoji = true;
//self.allow_caps = false;
//后缀允许单个图⽚的缓存清除
//self.img_suffix = '';
//初始化
self.inits = {};
self.map = {};
//初始化环境设置
self.init_env();
return self;url编码和utf8区别
}
emoji.prototype.init_env = function(){
var self = this;
if(v) return;
v = 1;
self.supports_css = false;
/
/检测设备类型,省略
//获得⼿机浏览器类型
var ua = navigator.userAgent;
//需要⼀个更好的⽅法来检测Android端对emoji的⽀持情况
if(false && ua.match(/Android/i)){
return;
}
if(self.supports_css){
}
/
/没有其他的检测——使⽤图⽚
};
Conflict = function(){
root.EmojiConvertor = previous_emoji;
return emoji;
}
//初始化图标字符串数据
emoji.prototype.init_colons = function(){
var self = this;
if(lons) return;
lons = 1;
<_colons = new RegExp('\:[a-zA-Z0-9-_+]+\:(\:skin-tone-[2-6]\:)?','g');
lons = {};
for(var i in self.data){ //关于data的定义放在本⽂件的最后
for(var j = 0; j < self.data[i][3].length; j ++){
lons[self.data[i][3][j]] = i;
}
}
}
//
emoji.prototype.escape_rx = function(text){
place(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
//初始化⽂本表情图标数据
emoji.prototype.init_emoticons = function(){
var self = this;
if(icons) return;
//调⽤它初始化emoticons map
self.init_colons();
icons = 1;
var a = [];
icons = {};
for(var i icons_data){//emoticons_data定义在最后
/
/将&,<,>符号转成html转义字符
var emoticon = i.replace(/\&/g,'&').replace(/\</g,'<').replace(/\>/g,'>');
if(!icons_data[i]]) continue;
icons[emoticon] = icons_data[i]];
a.push(self.escape_rx(emoticon));
}
<_emoticons = new RegExp(('(^|\\s)('+a.join('|')+')(?=$|[\\s|\\?\\.,!])'),'g');
};
//使⽤冒号代替情感符
place_emoticons_with_colons = function(str){
var self = this;
self.init_emoticons();
var _prev_offset = 0;
var emoticons_with_parens = [];
var str_replaced = _emoticons,function(m,$1,emoticon,offset){
var prev_offset = _prev_offset;
_prev_offset = offset + m.length;
var has_open_paren = emoticon.indexOf('(') !== -1;
var has_close_paren = emoticon.indexOf(')') !== -1;
/*
Track paren-having emoticons for fixing later
*/
if((has_open_paren || has_close_paren) && emoticons_with_parens.indexOf(emoticon) == -1){ emoticons_with_parens.push(emoticon);
}
//查具有闭括号不含有开括号符号
if(has_close_paren && !has_open_paren){
var piece = str.substring(prev_offset,offset);
if(piece.indexOf('(') !== -1 && piece.indexOf(')') === -1) return m;
if(piece.indexOf('(') !== -1 && piece.indexOf(')') === -1) return m;
}
//see if we are in a numbered list
if(m === '\n8)'){
var before_match = str.substring(0,offset);
if(/\n?(6\)|7\))/.test(before_match)) return m;
}
var val = self.data[icons[emoticon]][3][0];
return val ? $1 + ':' + val + ':' : m;
});
//固定我们忽略的情感符
if(emoticons_with_parens.length){
var escaped_emoticons = emoticons_with_parens.map(self.escape_rx);
var parenthetical_rx = new RegExp('(\\(.+)('+escaped_emoticons.join('|')+')(.+\\))', 'g');
str_replaced = place(parenthetical_rx, function(m,$1,emoticon,$2){
var val = self.data[icons[emoticon]][3][0];
return val ? $1 + ':' + val + ':' + $2 : m;
});
}
return str_replaced;
}
//⽤合适的字符做⼀个实际的替换
placement = function(idx,actual,wrapper,variation){
var self = this;
//对于变动的修饰器,设置'extra'给单独输出的修饰语
var extra = '';
var variation_idx = 0;
if(typeof variation === 'object'){
extra = placement(variation.idx,variation.actual, variation.wrapper);
variation_idx = idx + '-' + variation.idx;
}
var img_set = self.img_set;
//这⾥有对于精灵图和css的处理
//处理简单模式(冒号和⽂本)
wrapper = wrapper || '';
lons_mode) return ':' + self.data[idx][3][0] + ':' + extra;
var text_name = (actual) ? wrapper + actual + wrapper : self.data[idx][8] || wrapper + self.data[idx][3][0] + wrapper;
_mode) return text_name + extra;
//本地模式,直接原样输出有兼容软银和⾕歌
place_mode == 'unified' && self.allow_native && self.data[idx][0][0]) return self.data[idx][0][0] + extra;
/*place_mode == 'softbank' && self.allow_native && self.data[idx][1]) return self.data[idx][1] + extra;
place_mode == 'google' && self.allow_native && self.data[idx][2]) return self.data[idx][2] + extra;*/
//处理图⽚模式的
/*
这⾥的变量选择有些复杂——如果图⽚设置和特定的表情⽀持变量,那么使⽤变量图⽚。否则,返回⼀个已经在'extra'中计算好的变量作为单独的图⽚ */
//⾸先我们设置⼀些将要被⽤到的参数,如果不能使⽤变量
var img = self.data[idx][7] || self.img_sets[img_set].path + idx + '.png';// + self.img_suffix;
var title = self.include_title ? ' title="' + (actual || self.data[idx][3][0]) + '"' : '';
//var text = self.include_text ? wrapper + (actual || self.data[idx][3][0]) + wrapper : '';
var px = self.data[idx][4];
var py = self.data[idx][5];
/*
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论