自定义函数 JSA_A_UINT8ARRAYTOUTF16TOSTRING 将UTF-16解码为字符

function JSA_A_UINT8ARRAYTOUTF16TOSTRING(uint8Array, format, endianness, hasBom) {
       //表格中使用函数,参数留空时,默认值处理
    uint8Array = uint8Array === -2147352572 ? undefined : uint8Array;
    format = format === -2147352572 ? undefined : format;
    endianness = endianness === -2147352572 ? undefined : endianness;
    hasBom = hasBom === -2147352572 ? undefined : hasBom;
    
    // 参数验证和默认值处理
    uint8Array = (Array.isArray(uint8Array.valueOf()) || (uint8Array instanceof Uint8Array)) ? Array.from(uint8Array.valueOf()).flat(Infinity).filter(v => v !== null && v !== undefined && v !== "") : [uint8Array.valueOf()].filter(v => v !== null && v !== undefined && v !== "");
    format = (format || 'dec').toLowerCase();
    endianness = (endianness || 'BE').toUpperCase();
    hasBom = hasBom || false;
    
    // 验证参数有效性
    if (uint8Array.length === 0) {
        return "#N/A";
    }
    
    if (!['bin', 'hex', 'dec'].includes(format)) {
        return "#N/A";
    }
    
    if (!['BE', 'LE'].includes(endianness)) {
        return "#N/A";
    }
    
    const processInput = (data, format) => { // 处理输入格式,转为十进制数组
        switch (format.toLowerCase()) {
            case 'bin':
                return data.map(x => parseInt(x, 2));
            case 'hex':
                return data.map(x => parseInt(x, 16));
            case 'dec':
                return Array.isArray(data[0]) ? data.flat() : data;
            default:
                return "#N/A";
        }
    };
    
    const checkAndRemoveBom = (data, endianness, hasBomFlag) => { // 检查并移除BOM
        const bom = endianness.toUpperCase() === 'BE' ? [254, 255] : [255, 254];
        
        if (hasBomFlag && data.length >= 2 && data[0] === bom[0] && data[1] === bom[1]) {
            return data.slice(2);
        }
        
        return data;
    };
    
    const bytesToWords = (bytes, endianness) => { // 将字节转换为16位字
        if (bytes.length % 2 !== 0) {
            return "#N/A";
        }
        
        const words = [];
        const endian = endianness.toUpperCase();
        
        for (let i = 0; i < bytes.length; i += 2) {
            let word;
            
            if (endian === 'BE') {
                word = (bytes[i] << 8) | bytes[i + 1];
            } else { // LE
                word = (bytes[i + 1] << 8) | bytes[i];
            }
            
            words.push(word);
        }
        
        return words;  //二进制为16位的数字组成的数组
    };
    
    const decodeWords = (words) => { // 解码16位字为字符串
        let result = '';
        
        for (let i = 0; i < words.length; i++) {
            const currentWord = words[i];
            const prevWord = i > 0 ? words[i - 1] : 0;
            const nextWord = i < (words.length - 1) ? words[i + 1] : 0;
            const isHighSurrogate = currentWord >= 55296 && currentWord <= 56319;
            const isLowSurrogate = currentWord >= 56320 && currentWord <= 57343;
            const hasValidPair = isHighSurrogate && i < words.length - 1 && nextWord >= 56320 && nextWord <= 57343;
            let char;
            
            if (hasValidPair) { // 处理代理对
                const high_10 = currentWord & 1023;
                const low_10 = nextWord & 1023;
                const codePoint = ((high_10 << 10) | low_10) + 65536;
                char = String.fromCodePoint(codePoint);
                i++; // 跳过下一个字,因为已经处理了
            } else if (isLowSurrogate && i > 0 && prevWord >= 55296 && prevWord <= 56319) { // 如果是低代理且前一个是高代理,说明已经在上一次迭代中处理过了
                char = '';
            } else { // 直接转换基本多文种平面字符
                char = String.fromCharCode(currentWord);
            }
            
            result += char;
        }
        
        return result;
    };

    try {
        const processedData = processInput(uint8Array, format); // 处理输入数据,转为十进制数组
        const dataWithoutBom = checkAndRemoveBom(processedData, endianness, hasBom); // 检查并移除BOM
        const validData = dataWithoutBom.length % 2 === 0 ? dataWithoutBom : dataWithoutBom.slice(0, -1); // 确保数据长度为偶数
        const words = bytesToWords(validData, endianness); // 将字节转换为16位字
        return decodeWords(words); // 解码为字符串
    } catch(error) {
        return "#N/A";
    }
}

插入函数对话框、函数参数对话框:

加载宏文件function Workbook_Open(){}中添加以下代码。

Application.MacroOptions("JSA_A_UINT8ARRAYTOUTF16TOSTRING", "将UTF-16编码的Uint8Array解码为字符串。", undefined, undefined, undefined, undefined, 14, undefined, undefined, undefined, ['UTF-16编码的Uint8Array,也可以是单行或多行数组。', '输入字节的格式。"dec":十进制字节值(默认),"hex":十六进制字节值,"bin":二进制字节值。', '字节序,"utf-16"需指定。"BE":大端序(高位字节在前)(默认),"LE":小端序(低位字节在前)。', '是否包含字节序标记(BOM),"utf-16"需指定。TRUE:包含,FALSE:不包含(默认)。']);

云南省
浏览 23
收藏
1
分享
1 +1
1
+1
全部评论 1
 
497128657
关系图:https://bbs.wps.cn/topic/68275
· 云南省
回复