在 web 开发中,base64 编码是一种常见的数据转换方式。它通过将二进制数据转换为文本数据,便于在 http 请求、url 中传输或存储。然而,处理中文字符时,base64 编码会面临一些特殊的挑战,因为中文字符通常占用多个字节,而 base64 编码是基于字节的。在本文中,我们将介绍两种方法来处理中文字符串的 base64 编码与解码。
为什么 base64 编码会与中文字符发生冲突?
base64 编码是一种将二进制数据转换为 ascii 字符串格式的方式。每个字符占用 6 位,而 base64 编码本身的原理是将输入数据按照每 6 位拆分,并映射到对应的 base64 字符上。
然而,中文字符在 utf-8 编码下通常需要多个字节(通常是 3 个字节)。因此,如果我们直接对中文字符进行 base64 编码而没有正确处理字符编码,可能会导致编码错误或者解码时出现乱码。为了避免这个问题,我们需要先将中文字符转换为 utf-8 字节,然后再进行 base64 编码。
在本文中,我们将介绍两种不同的方式来解决这个问题,分别是手动实现 base64 编码和解码的方式,以及使用 textencoder 和 textdecoder api 来处理编码和解码。
方法一:手动实现 base64 编码与解码
在这个方法中,我们手动处理每个字节,并将字节转化为二进制字符串。然后,我们将二进制字符串按每 6 位进行拆分,映射为 base64 字符。解码时,我们通过反向操作将 base64 字符还原为二进制数据,然后恢复为原始的 utf-8 字符串。
(1) 中文字符串的 base64 编码
function base64encode(input) {
    const base64chars = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/';
    // 将字符串转换为 utf-8 字节
    let utf8bytes = new textencoder().encode(input);
    // 将每个字节转换为二进制字符串
    let binarystring = '';
    for (let i = 0; i < utf8bytes.length; i++) {
        binarystring += utf8bytes[i].tostring(2).padstart(8, '0');
    }
    // 按 6 位拆分
    const chunks = [];
    for (let i = 0; i < binarystring.length; i += 6) {
        chunks.push(binarystring.slice(i, i + 6));
    }
    // 如果最后一组少于 6 位,进行填充
    if (chunks[chunks.length - 1].length < 6) {
        chunks[chunks.length - 1] = chunks[chunks.length - 1].padend(6, '0');
    }
    // 查找对应的 base64 字符
    let base64encoded = chunks.map(chunk => {
        const index = parseint(chunk, 2); // 将二进制转换为数字
        return base64chars.charat(index);
    }).join('');
    // 添加填充字符
    while (base64encoded.length % 4 !== 0) {
        base64encoded += '=';
    }
    return base64encoded;
}
// 示例
const input = '你好润,base64!';
const encoded = base64encode(input);
console.log('encoded:', encoded);// encoded: 5l2g5aw95ram77ymqmfzzty077yb
解释:
- utf-8 编码:通过 
textencoder().encode(input)方法,我们将输入的中文字符串转换为 utf-8 字节。每个字节在 utf-8 编码中通常会占用多个字节(例如中文字符通常占用 3 个字节)。 - 二进制转换:我们将每个字节转为二进制字符串,并将它们合并成一个长的二进制串。
 - base64 编码:通过按每 6 位将二进制字符串拆分,我们将每一组 6 位的二进制数转换为对应的 base64 字符。
 - 填充字符:base64 编码要求输出的字符数必须是 4 的倍数,因此我们在末尾添加 
=字符进行填充。 
(2) 中文字符串的 base64 解码
function base64decode(input) {
    const base64chars = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/';
    // 去除填充字符 '='
    input = input.replace(/=/g, '');
    // 将每个 base64 字符转换为 6 位二进制
    let binarystring = '';
    for (let i = 0; i < input.length; i++) {
        const index = base64chars.indexof(input.charat(i)); // 查找字符的位置
        binarystring += index.tostring(2).padstart(6, '0'); // 将位置转换为 6 位二进制
    }
    // 每 8 位一个字节,转换为字节
    let decodedbytes = [];
    for (let i = 0; i < binarystring.length; i += 8) {
        const byte = binarystring.slice(i, i + 8);
        decodedbytes.push(parseint(byte, 2)); // 将二进制转为字节
    }
    // 将字节数组转换为 utf-8 字符串
    let decodedstring = new textdecoder().decode(new uint8array(decodedbytes));
    return decodedstring;
}
// 示例
const decoded = base64decode(encoded);
console.log('decoded:', decoded);//decoded: 你好润,base64!
解释:
- base64 解码:首先将 base64 字符串转换为 6 位二进制字符串。然后每 8 位恢复为一个字节。
 - 还原字符:通过 
textdecoder将解码后的字节数组还原为 utf-8 字符串。 
方法二:使用 textencoder 和 textdecoder api
如果不想手动实现 base64 编码和解码的过程,现代浏览器提供了 textencoder 和 textdecoder api,可以帮助我们简化编码和解码过程。我们可以直接使用这些 api 来将中文字符串转换为字节数组,再进行 base64 编码。
(1) 中文字符串的 base64 编码
function base64encodeusingapi(input) {
    // 使用 textencoder 将字符串转换为 utf-8 字节
    const utf8bytes = new textencoder().encode(input);
    // 将字节数组转换为 base64 字符串
    return btoa(string.fromcharcode.apply(null, utf8bytes));
}
// 示例
const input = '你好red润,base64!';
const encoded = base64encodeusingapi(input);
console.log('encoded:', encoded);//encoded: 5l2g5aw9cmvk5ram77ymqmfzzty077yb
解释:
- textencoder:通过 
textencoder将字符串转换为 utf-8 字节数组。 btoa:btoa是一个内建的 javascript 函数,用于将二进制数据转换为 base64 编码的字符串。需要注意的是,btoa只能处理 8 位字符,因此我们通过string.fromcharcode.apply方法将字节数组转换为字符串,然后进行编码。
(2) 中文字符串的 base64 解码
function base64decodeusingapi(input) {
    // 使用 atob 解码 base64 字符串
    const decodeddata = atob(input);
    // 将解码后的字符串转换为字节数组
    const bytearray = new uint8array(decodeddata.length);
    for (let i = 0; i < decodeddata.length; i++) {
        bytearray[i] = decodeddata.charcodeat(i);
    }
    // 使用 textdecoder 将字节数组转换为原始字符串
    return new textdecoder().decode(bytearray);
}
// 示例
const decoded = base64decodeusingapi(encoded);
console.log('decoded:', decoded);// decoded: 你好red润,base64!
解释:
atob:atob函数用于解码 base64 字符串。解码后的数据是一个原始的二进制字符串。- textdecoder:通过 
textdecoder将字节数组还原为 utf-8 字符串。 
总结
在处理中文字符串的 base64 编码与解码时,关键在于如何正确地将字符转换为字节数据。通过手动处理每个字节或使用现代的 textencoder 和 textdecoder api,我们可以确保中文字符能够正确地进行 base64 编码与解码。
- 手动实现:适用于那些需要详细控制编码过程的场景。你可以深入理解 base64 编码的每个细节,并根据需要进行优化。
 - 使用 api:对于大多数情况,
textencoder和textdecoderapi 提供了一种更简洁、直接的方式来处理编码和解码,减少了手动操作的复杂性。 
到此这篇关于javascript处理中文字符串的base64编码与解码的两种方法的文章就介绍到这了,更多相关javascript处理base64编码与解码内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
            
                                            
                                            
                                            
                                            
                                            
发表评论