Base64
关于 Base64 编码
Base64 是网络上最常见的用于传输 8Bit 字节码的编码方式之一,Base64 是一种基于 64 个可打印字符来表示二进制数据的方法。由于 a-z
、A-Z
、数字 0-9
、符号 +
、/
一共 64 个字符的字符集,任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做 Base64 编码。
Base64 编码是从二进制到字符的过程,可用于在 HTTP 环境下传递较长的标识信息。采用 Base64 编码具有不可读性,需要解码后才能阅读。
Base64 维基百科 (opens new window)
# Python 3.0+
import base64
data = "spiderapi.cn - 虫术"
result_encoded = base64.b64encode(data.encode("utf-8")).decode("utf-8")
result_decoded = base64.b64decode(result_encoded).decode("utf-8")
print("Base64 编码值:", result_encoded) # c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
print("Base64 解码值:", result_decoded)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 不借助官方或者第三方库,纯源码实现
def base64_encode(input_string):
base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
result = ""
# 将输入字符串转换为字节
input_bytes = input_string.encode("utf-8")
for i in range(0, len(input_bytes), 3):
chunk = input_bytes[i:i + 3]
# 将每个字符转换为ASCII码
chunk_bytes = [byte for byte in chunk]
# 将三个字节合并为一个24位的二进制字符串
binary_string = "".join(format(byte, "08b") for byte in chunk_bytes)
# 根据需求在二进制字符串末尾补0
while len(binary_string) % 24 != 0:
binary_string += "0"
# 将24位的二进制字符串切分为6位的小块
six_bit_chunks = [binary_string[j:j + 6] for j in range(0, len(binary_string), 6)]
# 将每个6位的二进制字符串转换为相应的Base64字符
for six_bit_chunk in six_bit_chunks:
if len(six_bit_chunk) < 6:
six_bit_chunk = six_bit_chunk.ljust(6, '0')
result += base64_chars[int(six_bit_chunk, 2)]
# 对不足3个字符的情况进行Base64填充
padding = len(input_bytes) % 3
if padding == 1:
result += "=="
elif padding == 2:
result += "="
return result
def base64_decode(encoded_string):
base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
result = bytearray()
# 对于每4个Base64字符,将其解码为3个原始字符
for i in range(0, len(encoded_string), 4):
chunk = encoded_string[i:i + 4]
# 将每个Base64字符转换为其对应的6位二进制字符串
binary_string = ""
for char in chunk:
if char != "=":
binary_string += format(base64_chars.index(char), "06b")
# 将24位的二进制字符串切分为8位的字符
eight_bit_chunks = [binary_string[j:j + 8] for j in range(0, len(binary_string), 8)]
# 将每个8位的二进制字符串转换为相应的字节
for eight_bit_chunk in eight_bit_chunks:
result.append(int(eight_bit_chunk, 2))
return result.decode("utf-8")
if __name__ == "__main__":
data = "spiderapi.cn - 虫术"
result_encoded = base64_encode(data)
result_decoded = base64_decode(result_encoded)
print("Base64 编码值:", result_encoded) # c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
print("Base64 解码值:", result_decoded)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Make sure to add code blocks to your code group
# JavaScript Node.js ECMAScript 5.1+
// 使用内置函数 btoa 和 atob
// 需要注意的是函数仅支持编码 Latin1 字符集,所以像汉字这样的字符集无法编码,需要将字符串作为 URI 组件进行编码后再进行 Base64 编码。
var dataLatin1 = "spiderapi.cn";
var dataChinese = "spiderapi.cn - 虫术";
var resultEncodedLatin1 = btoa(dataLatin1);
var resultDecodedLatin1 = atob(resultEncodedLatin1);
var resultEncodedChinese = btoa(unescape(encodeURIComponent(dataChinese)));
var resultDecodedChinese = decodeURIComponent(escape(atob(resultEncodedChinese)));
console.log("Base64 英文编码值:", resultEncodedLatin1) // c3BpZGVyYXBpLmNu
console.log("Base64 英文解码值:", resultDecodedLatin1)
console.log("Base64 中文编码值:", resultEncodedChinese) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
console.log("Base64 中文解码值:", resultDecodedChinese)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Node 环境内置方法
var data = "spiderapi.cn - 虫术";
var resultEncoded = new Buffer.from(data).toString("base64");
var resultDecoded = new Buffer.from(resultEncoded, "base64").toString();
console.log("Base64 编码值:", resultEncoded) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
console.log("Base64 解码值:", resultDecoded)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
// 安装依赖 npm install crypto-js
var CryptoJS = require("crypto-js");
var data = "spiderapi.cn - 虫术";
var resultEncoded = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data));
var resultDecoded = CryptoJS.enc.Base64.parse(resultEncoded).toString(CryptoJS.enc.Utf8);
console.log("Base64 编码值:", resultEncoded) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
console.log("Base64 解码值:", resultDecoded)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
// 不借助官方或者第三方库,纯源码实现
var CryptoJS = CryptoJS || (function (Math, undefined) {
var crypto;
if (typeof window !== 'undefined' && window.crypto) {
crypto = window.crypto;
}
if (typeof self !== 'undefined' && self.crypto) {
crypto = self.crypto;
}
if (typeof globalThis !== 'undefined' && globalThis.crypto) {
crypto = globalThis.crypto;
}
if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
crypto = window.msCrypto;
}
if (!crypto && typeof global !== 'undefined' && global.crypto) {
crypto = global.crypto;
}
if (!crypto && typeof require === 'function') {
try {
crypto = require('crypto');
} catch (err) {}
}
var cryptoSecureRandomInt = function () {
if (crypto) {
if (typeof crypto.getRandomValues === 'function') {
try {
return crypto.getRandomValues(new Uint32Array(1))[0];
} catch (err) {}
}
if (typeof crypto.randomBytes === 'function') {
try {
return crypto.randomBytes(4).readInt32LE();
} catch (err) {}
}
}
throw new Error('Native crypto module could not be used to get secure random number.');
};
var create = Object.create || (function () {
function F() {}
return function (obj) {
var subtype;
F.prototype = obj;
subtype = new F();
F.prototype = null;
return subtype;
};
}());
var C = {};
var C_lib = C.lib = {};
var Base = C_lib.Base = (function () {
return {
extend: function (overrides) {
var subtype = create(this);
if (overrides) {
subtype.mixIn(overrides);
}
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
subtype.init = function () {
subtype.$super.init.apply(this, arguments);
};
}
subtype.init.prototype = subtype;
subtype.$super = this;
return subtype;
}, create: function () {
var instance = this.extend();
instance.init.apply(instance, arguments);
return instance;
}, init: function () {}, mixIn: function (properties) {
for (var propertyName in properties) {
if (properties.hasOwnProperty(propertyName)) {
this[propertyName] = properties[propertyName];
}
}
if (properties.hasOwnProperty('toString')) {
this.toString = properties.toString;
}
}, clone: function () {
return this.init.prototype.extend(this);
}
};
}());
var WordArray = C_lib.WordArray = Base.extend({
init: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes != undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 4;
}
}, toString: function (encoder) {
return (encoder || Hex).stringify(this);
}, concat: function (wordArray) {
var thisWords = this.words;
var thatWords = wordArray.words;
var thisSigBytes = this.sigBytes;
var thatSigBytes = wordArray.sigBytes;
this.clamp();
if (thisSigBytes % 4) {
for (var i = 0; i < thatSigBytes; i++) {
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
}
} else {
for (var j = 0; j < thatSigBytes; j += 4) {
thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2];
}
}
this.sigBytes += thatSigBytes;
return this;
}, clamp: function () {
var words = this.words;
var sigBytes = this.sigBytes;
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
words.length = Math.ceil(sigBytes / 4);
}, clone: function () {
var clone = Base.clone.call(this);
clone.words = this.words.slice(0);
return clone;
}, random: function (nBytes) {
var words = [];
var r = (function (m_w) {
var m_w = m_w;
var m_z = 0x3ade68b1;
var mask = 0xffffffff;
return function () {
m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
var result = ((m_z << 0x10) + m_w) & mask;
result /= 0x100000000;
result += 0.5;
return result * (Math.random() > .5 ? 1 : -1);
}
});
var RANDOM = false, _r;
try {
cryptoSecureRandomInt();
RANDOM = true;
} catch (err) {}
for (var i = 0, rcache; i < nBytes; i += 4) {
if (!RANDOM) {
_r = r((rcache || Math.random()) * 0x100000000);
rcache = _r() * 0x3ade67b7;
words.push((_r() * 0x100000000) | 0);
continue;
}
words.push(cryptoSecureRandomInt());
}
return new WordArray.init(words, nBytes);
}
});
var C_enc = C.enc = {};
var Hex = C_enc.Hex = {
stringify: function (wordArray) {
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var hexChars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
hexChars.push((bite >>> 4).toString(16));
hexChars.push((bite & 0x0f).toString(16));
}
return hexChars.join('');
}, parse: function (hexStr) {
var hexStrLength = hexStr.length;
var words = [];
for (var i = 0; i < hexStrLength; i += 2) {
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
}
return new WordArray.init(words, hexStrLength / 2);
}
};
var Latin1 = C_enc.Latin1 = {
stringify: function (wordArray) {
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var latin1Chars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
latin1Chars.push(String.fromCharCode(bite));
}
return latin1Chars.join('');
}, parse: function (latin1Str) {
var latin1StrLength = latin1Str.length;
var words = [];
for (var i = 0; i < latin1StrLength; i++) {
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
}
return new WordArray.init(words, latin1StrLength);
}
};
var Utf8 = C_enc.Utf8 = {
stringify: function (wordArray) {
try {
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
} catch (e) {
throw new Error('Malformed UTF-8 data');
}
}, parse: function (utf8Str) {
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
}
};
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
reset: function () {
this._data = new WordArray.init();
this._nDataBytes = 0;
}, _append: function (data) {
if (typeof data == 'string') {
data = Utf8.parse(data);
}
this._data.concat(data);
this._nDataBytes += data.sigBytes;
}, _process: function (doFlush) {
var processedWords;
var data = this._data;
var dataWords = data.words;
var dataSigBytes = data.sigBytes;
var blockSize = this.blockSize;
var blockSizeBytes = blockSize * 4;
var nBlocksReady = dataSigBytes / blockSizeBytes;
if (doFlush) {
nBlocksReady = Math.ceil(nBlocksReady);
} else {
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
}
var nWordsReady = nBlocksReady * blockSize;
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
if (nWordsReady) {
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
this._doProcessBlock(dataWords, offset);
}
processedWords = dataWords.splice(0, nWordsReady);
data.sigBytes -= nBytesReady;
}
return new WordArray.init(processedWords, nBytesReady);
}, clone: function () {
var clone = Base.clone.call(this);
clone._data = this._data.clone();
return clone;
}, _minBufferSize: 0
});
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
cfg: Base.extend(),
init: function (cfg) {
this.cfg = this.cfg.extend(cfg);
this.reset();
}, reset: function () {
BufferedBlockAlgorithm.reset.call(this);
this._doReset();
}, update: function (messageUpdate) {
this._append(messageUpdate);
this._process();
return this;
}, finalize: function (messageUpdate) {
if (messageUpdate) {
this._append(messageUpdate);
}
var hash = this._doFinalize();
return hash;
}, blockSize: 512 / 32,
_createHelper: function (hasher) {
return function (message, cfg) {
return new hasher.init(cfg).finalize(message);
};
}, _createHmacHelper: function (hasher) {
return function (message, key) {
return new C_algo.HMAC.init(hasher, key).finalize(message);
};
}
});
var C_algo = C.algo = {};
return C;
}(Math));
(function () {
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_enc = C.enc;
var Base64 = C_enc.Base64 = {
stringify: function (wordArray) {
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var map = this._map;
wordArray.clamp();
var base64Chars = [];
for (var i = 0; i < sigBytes; i += 3) {
var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
for (var j = 0;
(j < 4) && (i + j * 0.75 < sigBytes); j++) {
base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
}
}
var paddingChar = map.charAt(64);
if (paddingChar) {
while (base64Chars.length % 4) {
base64Chars.push(paddingChar);
}
}
return base64Chars.join('');
}, parse: function (base64Str) {
var base64StrLength = base64Str.length;
var map = this._map;
var reverseMap = this._reverseMap;
if (!reverseMap) {
reverseMap = this._reverseMap = [];
for (var j = 0; j < map.length; j++) {
reverseMap[map.charCodeAt(j)] = j;
}
}
var paddingChar = map.charAt(64);
if (paddingChar) {
var paddingIndex = base64Str.indexOf(paddingChar);
if (paddingIndex !== -1) {
base64StrLength = paddingIndex;
}
}
return parseLoop(base64Str, base64StrLength, reverseMap);
}, _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
};
function parseLoop(base64Str, base64StrLength, reverseMap) {
var words = [];
var nBytes = 0;
for (var i = 0; i < base64StrLength; i++) {
if (i % 4) {
var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);
nBytes++;
}
}
return WordArray.create(words, nBytes);
}
}());
var data = "spiderapi.cn - 虫术";
var resultEncoded = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data));
var resultDecoded = CryptoJS.enc.Base64.parse(resultEncoded).toString(CryptoJS.enc.Utf8);
console.log("Base64 编码值:", resultEncoded) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
console.log("Base64 解码值:", resultDecoded)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
// 不借助官方或者第三方库,纯源码实现
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64.utf8Encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output += Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
}
return output;
},
decode: function(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = Base64._keyStr.indexOf(input.charAt(i++));
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
enc4 = Base64._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output += String.fromCharCode(chr1);
if (enc3 !== 64) {
output += String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output += String.fromCharCode(chr3);
}
}
output = Base64.utf8Decode(output);
return output;
},
utf8Encode: function(string) {
string = string.replace(/\r\n/g, "\n");
var utfText = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utfText += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utfText += String.fromCharCode((c >> 6) | 192);
utfText += String.fromCharCode((c & 63) | 128);
} else {
utfText += String.fromCharCode((c >> 12) | 224);
utfText += String.fromCharCode(((c >> 6) & 63) | 128);
utfText += String.fromCharCode((c & 63) | 128);
}
}
return utfText;
},
utf8Decode: function(utfText) {
var string = "";
var i = 0;
var c, c1, c2;
while (i < utfText.length) {
c = utfText.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utfText.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utfText.charCodeAt(i + 1);
var c3 = utfText.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
};
var data = "spiderapi.cn - 虫术";
var resultEncoded = Base64.encode(data);
var resultDecoded = Base64.decode(resultEncoded);
console.log("Base64 编码值:", resultEncoded) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
console.log("Base64 解码值:", resultDecoded)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Make sure to add code blocks to your code group
# Golang 1.0+
package main
import (
"encoding/base64"
"fmt"
)
func main() {
data := "spiderapi.cn - 虫术"
resultEncoded := base64.StdEncoding.EncodeToString([]byte(data))
resultDecoded, err := base64.StdEncoding.DecodeString(resultEncoded)
if err != nil {
fmt.Println("Base64 decode error:", err)
return
}
fmt.Println("Base64 编码值:", resultEncoded) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
fmt.Println("Base64 解码值:", string(resultDecoded))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 不借助官方或者第三方库,纯源码实现
package main
import "fmt"
const (
base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
)
func base64Encode(data []byte) []byte {
var result []byte
pad := len(data) % 3
for i := 0; i < len(data); i += 3 {
threeBytes := (int(data[i]) << 16) | (int(data[i+1]) << 8) | int(data[i+2])
result = append(result, base64Table[(threeBytes>>18)&0x3F])
result = append(result, base64Table[(threeBytes>>12)&0x3F])
result = append(result, base64Table[(threeBytes>>6)&0x3F])
result = append(result, base64Table[threeBytes&0x3F])
}
if pad > 0 {
result[len(result)-1] = '='
if pad == 1 {
result[len(result)-2] = '='
}
}
return result
}
func base64Decode(input string) ([]byte, error) {
var result []byte
pad := 0
if input[len(input)-1] == '=' {
pad++
}
if input[len(input)-2] == '=' {
pad++
}
for i := 0; i < len(input); i += 4 {
oneBytes := (index(input[i]) << 18) | (index(input[i+1]) << 12) | (index(input[i+2]) << 6) | index(input[i+3])
result = append(result, byte((oneBytes>>16)&0xFF))
result = append(result, byte((oneBytes>>8)&0xFF))
result = append(result, byte(oneBytes&0xFF))
}
return result[:len(result)-pad], nil
}
func index(char byte) int {
for i := 0; i < len(base64Table); i++ {
if base64Table[i] == char {
return i
}
}
return -1
}
func main() {
data := "spiderapi.cn - 虫术"
resultEncoded := base64Encode([]byte(data))
resultDecoded, err := base64Decode(string(resultEncoded))
if err != nil {
fmt.Println("Base64 decode error:", err)
return
}
fmt.Println("Base64 编码值:", string(resultEncoded)) // c3BpZGVyYXBpLmNuIC0g6Jmr5pyv
fmt.Println("Base64 解码值:", string(resultDecoded))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Make sure to add code blocks to your code group
# 主要特征
Base64 是我们最常见的编码,除此之外,其实还有 Base16、Base32、Base58、Base85、Base100 等,Base 系列主要特征如下:
- Base16:结尾没有等号,数字要多于字母;
- Base32:字母要多于数字,明文数量超过10个,结尾可能会有很多等号;
- Base58:结尾没有等号,字母要多于数字;
- Base64:一般情况下结尾都会有1个或者2个等号,明文很少的时候可能没有,由
a-z、A-Z、0-9、+、/
组成; - Base85:等号一般出现在字符串中间,含有一些奇怪的字符;
- Base100:密文由 Emoji 表情组成。
示例:
编码类型 | 示例一 | 示例二 |
---|---|---|
明文 | 01234567890 | administrators |
Base16 | 3031323334353637383930 | 61646D696E6973747261746F7273 |
Base32 | GAYTEMZUGU3DOOBZGA====== | MFSG22LONFZXI4TBORXXE4Y= |
Base58 | cX8j8pvGzppMKVb | BNF5dFLUTN5XwM1yLoF |
Base64 | MDEyMzQ1Njc4OTA= | YWRtaW5pc3RyYXRvcnM= |
Base85 | 0JP==1c70M3&rY | @:X4hDJ=06Eaa'.EcV |
Base100 | 🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐧 | 👘👛👤👠👥👠👪👫👩👘👫👦👩👪 |
# 在线工具
帮助我们改善此页 (opens new window)
上次更新: 2024/10/17, 09:54:53