很多网站js代码中都用了Base64编码和解码。
下面这段就是摘自某网站的js代码
define('base64', function(require, exports, module) {
var
object = typeof exports != 'undefined' ? exports : window,
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
INVALID_CHARACTER_ERR = (function () {
// fabricate a suitable error object
try { document.createElement('$'); }
catch (error) { return error; }}());
// encoder
// [https://gist.github.com/999166] by [https://github.com/nignag]
object.btoa || (
object.btoa = function (input) {
for (
// initialize result and counter
var block, charCode, idx = 0, map = chars, output = '';
// if the next input index does not exist:
// change the mapping table to "="
// check if d has no fractional digits
input.charAt(idx | 0) || (map = '=', idx % 1);
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
) {
charCode = input.charCodeAt(idx += 3/4);
if (charCode > 0xFF) throw INVALID_CHARACTER_ERR;
block = block << 8 | charCode;
}
return output;
});
object.base64encode = object.btoa;
// decoder
// [https://gist.github.com/1020396] by [https://github.com/atk]
object.atob || (
object.atob = function (input) {
input = input.replace(/=+$/, '')
if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR;
for (
// initialize result and counters
var bc = 0, bs, buffer, idx = 0, output = '';
// get next character
buffer = input.charAt(idx++);
// character found in table? initialize bit storage and add its ascii value;
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
// try to find character in table (0-63, not found => -1)
buffer = chars.indexOf(buffer);
}
return output;
});
object.base64decode = object.atob;
});
Base64介绍
Base64是网络上最常见的用于传输8Bit字节码的编码方式。详细介绍参见链接
它使用64个可见字符(英文字母大小写,0-9数字,斜杆’/’,加号 ‘+’)来表示二进制数。所以Base64编码是就是从二进制到文本(binary-to-text)的过程,具体编码原理如下。
编码原理
我们知道1个ASCII码占8位二进制,而1个Base64码是占6位二进制(2的6次方是64)。所以3个ASCII码就可以换成4个Base64码。
Base64编码原理就是,把每3个8Bit(二进制)的字节转换为4个6Bit(二进制)的字节(38 = 46 = 24),然后把6Bit再增加2位高位0,组成4个8Bit的字节,最后参照对照表获得编码后的字符。即:
字符a19–>ASCII(97 49 57)–>3组二进制(01100001 00110001 00111001)–>4组6位(011000 010011 000100 111001)–>高位补0–>(00011000 00010011 00000100 00111001)–>4个十进制数(24 19 4 57)-- >参照下面的对照表得到4个Base64编码字符(Y T E 5)
转换后的字符串理论上将要比原来的要长1/3。
注意:如果一个字符串按照每3个字符分组进行Base64编码之后,剩余需要编码的字符不够3个,那编码的结果也就不是4个字符,此时需要用等号‘=’补足。例如,字符‘o’,编码的结果就是’bw==’。
BASE64编码算法并不算是真正的加密算法。它只是将源数据转码成为了一种不易阅读的形式,而转码的规则是公开的。编码之后的数据显然无法阅读,需要解码后才能阅读。
Base解码就是上面的逆过程,只是不考虑等号‘=’。
Python中实现
爬网页代码一般都是在python中实现。所以如果在js中看到了本文开头引用的代码,也就是用Base64编码,那可以按照以下方式在python中来解码。
python中是通过base64库来实现Base64编码和解码的
import base64
a="a19"
print base64.b64encode(a)
结果’YTE5’
其余用法可以参见 https://blog.csdn.net/pengjunlee/article/details/91127222
Java中实现
package com.oy;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.junit.Test;
public class demo04 {
final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
@Test
public void testBase64() throws Exception {
byte[] textByte = "admin:123".getBytes(StandardCharsets.UTF_8);
String encodedText = encoder.encodeToString(textByte);//编码
System.out.println(encodedText);//YWRtaW46MTIz
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));//解码
}
}