活动介绍
file-type

JavaScript实现字符串转UTF-8字节序列

ZIP文件

下载需积分: 50 | 749B | 更新于2024-10-30 | 137 浏览量 | 1 下载量 举报 收藏
download 立即下载
在JavaScript中,字符串和字节序列的转换是一个常见的需求,尤其是在处理文本文件、网络请求数据以及进行本地数据存储时。UTF-8是一种广泛使用的字符编码标准,它可以表示Unicode标准中的任何字符,并且以其对中文、日文、韩文等非拉丁字符集的良好支持而受到青睐。JavaScript中的字符串默认是以UTF-16编码,而当需要将字符串转换为UTF-8编码的字节序列时,就需要使用特定的方法。 首先,我们需要了解在JavaScript中,字符和字节之间的基本区别。字符是抽象的概念,用于表示书写系统中的符号或符号的组合;而字节是存储和传输数据的单位,用于表示二进制数据。 在JavaScript中,可以使用`TextEncoder`接口来将字符串编码为UTF-8字节序列。`TextEncoder`是WHATWG Encoding Standard的一部分,并不是所有浏览器都支持。但在大多数现代浏览器中,包括最新的Chrome、Firefox和Edge,已经得到支持。 以下是如何在JavaScript中使用`TextEncoder`来将字符串转换为UTF-8字节序列的示例代码: ```javascript // 创建一个TextEncoder实例 const encoder = new TextEncoder(); // 要转换的字符串 const string = '你好,世界!'; // 使用TextEncoder的encode方法将字符串转换为Uint8Array类型的字节序列 const bytes = encoder.encode(string); // 输出字节序列 console.log(bytes); ``` 在上述代码中,我们首先创建了一个`TextEncoder`实例,然后调用`encode`方法并传入要转换的字符串,最后得到一个`Uint8Array`数组。`Uint8Array`是一个类型化数组,它表示一个8位无符号整数的数组。 对于那些还未支持`TextEncoder`的环境,可以使用一系列的位操作来手动实现字符串到UTF-8字节序列的转换。但是,由于现代浏览器支持度高,不推荐使用这种方法,因为它会更复杂且容易出错。 例如,手动转换的一个简化示例代码如下: ```javascript function stringToUTF8Bytes(str) { var utf8 = []; for (var i=0, n=str.length; i<n; i++) { var charcode = str.charCodeAt(i); if (charcode < 0x80) utf8.push(charcode); else if (charcode < 0x800) { utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f)); } else if (charcode < 0xd800 || charcode >= 0xe000) { utf8.push(0xe0 | (charcode >> 12), 0x80 | ((charcode >> 6) & 0x3f), 0x80 | (charcode & 0x3f)); } // 处理代理对 else { i++; // 注意: 这里假设str是有效的UTF-16并且已经处理过代理对 var charcode2 = str.charCodeAt(i); var surrogatePair = 0x10000 + (((charcode & 0x3ff) << 10) | (charcode2 & 0x3ff)); utf8.push(0xf0 | (surrogatePair >> 18), 0x80 | ((surrogatePair >> 12) & 0x3f), 0x80 | ((surrogatePair >> 6) & 0x3f), 0x80 | (surrogatePair & 0x3f)); } } return new Uint8Array(utf8); } // 使用自定义函数 var bytes = stringToUTF8Bytes('你好,世界!'); console.log(bytes); ``` 此示例中的`stringToUTF8Bytes`函数是一个简化的版本,仅用于说明如何手动进行转换。它不处理所有的边缘情况,并且对输入的字符串有特定的要求,比如必须是有效的UTF-16编码。 总结来说,虽然手动转换字符串到UTF-8字节序列可以完成,但`TextEncoder`提供了一个简洁、标准且兼容的方法。在开发中推荐使用现代浏览器原生支持的API,以保证代码的可维护性和兼容性。

相关推荐

filetype

const GMCrypt = require('gm-crypt').sm4; /** * SM4 解密函数(ECB模式 + PKCS5填充) * @param {string} base64Str - Base64编码的密文 * @param {string} key - 16字节密钥(HEX或字符串格式) * @returns {string|Uint8Array} - 解密后的数据(自动检测文本或二进制) */ export function decrypt(base64Str, key = 'HTHTqQq314159@26') { // SM4 配置(ECB模式 + PKCS5填充) const sm4Config = { key: key, mode: 'ecb', cipherType: 'base64', padding: 'pkcs5' }; const sm4 = new GMCrypt(sm4Config); try { // 1. 执行SM4解密(返回HEX字符串) const decryptedHex = sm4.decrypt(base64Str); // 2. 转换为字节数组 const bytes = hexToBytes(decryptedHex); // 3. 安全处理:过滤无效Unicode代码点 const safeBytes = bytes.filter(byte => byte <= 0x10FFFF); // 4. 尝试解码为UTF-8文本 try { return bytesToUtf8(safeBytes); } catch (textError) { // 解码失败则返回原始HEX数据 console.warn('解密结果非UTF-8文本,返回原始HEX数据'); return decryptedHex; } } catch (decryptError) { console.error('解密失败:', decryptError.message); throw new Error('SM4解密过程出错'); } } // HEX转字节数组 function hexToBytes(hex) { const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.substr(i, 2), 16); } return bytes; } // 字节数组转UTF-8字符串 function bytesToUtf8(bytes) { const decoder = new TextDecoder('utf-8'); return decoder.decode(bytes); }这段代码 和我本地的这个段代码 合并一下 // utils/sm4.ts import { sm4 } from 'sm-crypto'; // 配置 const sm4Config = { key: new TextEncoder().encode('b367d464d97caee1'), mode: 'ecb', cipherType: 'base64' }; // const sm4 = new SM4(sm4Config); export function encrypt(text) { // 返回 Base64,mode 和 gm-crypt 一致 return sm4.encrypt(text, sm4Config.key, { mode: 'ecb', cipherType: 'base64' }); } export function decrypt(base64Str) { // SM4 配置(ECB模式 + PKCS5填充) const sm4Config = { key: key, mode: 'ecb', cipherType: 'base64', padding: 'pkcs5' }; const sm4 = new GMCrypt(sm4Config); try { // 1. 执行SM4解密(返回HEX字符串) const decryptedHex = sm4.decrypt(base64Str); // 2. 转换为字节数组 const bytes = hexToBytes(decryptedHex); // 3. 安全处理:过滤无效Unicode代码点 const safeBytes = bytes.filter(byte => byte <= 0x10FFFF); // 4. 尝试解码为UTF-8文本 try { return bytesToUtf8(safeBytes); } catch (textError) { // 解码失败则返回原始HEX数据 console.warn('解密结果非UTF-8文本,返回原始HEX数据'); return decryptedHex; } } catch (decryptError) { console.error('解密失败:', decryptError.message); throw new Error('SM4解密过程出错'); } } // 工具函数:hex 转 utf8 字符串 function hexToUtf8(hex) { const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.substr(i, 2), 16); } const decoder = new TextDecoder('utf-8'); return decoder.decode(bytes); }

filetype

this.fileService.uploadFileToPath("CodeData.js", "js", dataString.getBytes(StandardCharsets.UTF_8), request); public FileDTO uploadFileToPath(String fileName, String path, byte[] bytes, HttpServletRequest request) throws Exception { FileHandleFactory fileHandle = this.getHandleFactory(); return fileHandle.uploadFileToPath(fileName, path, bytes, request); } public FileDTO uploadFileToPath(String fileName, String path, byte[] bytes, HttpServletRequest request) throws Exception { String rootRealPath = this.getRootRealPath(request); return this.uploadFileToPath(fileName, rootRealPath, path, bytes); } private FileDTO uploadFileToPath(String fileName, String rootRealPath, String destPath, byte[] bytes) throws Exception { if (StringUtils.isNotEmpty(destPath)) { if (!destPath.endsWith("/")) { destPath = destPath + "/"; } if (!destPath.startsWith("/")) { destPath = "/" + destPath; } } else { destPath = "/"; } String destRealPath = rootRealPath + destPath; try { File dir = new File(destRealPath); if (!dir.exists()) { dir.mkdirs(); } File file = new File(destRealPath + fileName); FileUtils.writeByteArrayToFile(file, bytes); } catch (Exception var8) { throw new ApplicationException("文件保存失败!"); } String fileExtName = fileName.lastIndexOf(".") > 0 ? fileName.substring(fileName.lastIndexOf(".") + 1) : ""; FileDTO dto = new FileDTO(); dto.setFileId(destPath + fileName); dto.setFileName(fileName); dto.setFileExtName(fileExtName); return dto; } 结合一下,查看一下CodeData.js输出到哪里去了

filetype

@GetMapping("/preview-main") public void previewPdf4ExcelMain(final HttpServletResponse response) throws Exception { this.service.previewPdf4ExcelMain(response); } @Override public void previewPdf4ExcelMain(HttpServletResponse response) throws Exception { InputStream ins = this.getClass().getResourceAsStream(IcpmBusiEnum.COST_EXPORT_MAIN_PDF.getCode()); Workbook poiWorkbook = new XSSFWorkbook(ins); ByteArrayOutputStream excelOut = new ByteArrayOutputStream(); poiWorkbook.write(excelOut); poiWorkbook.close(); this.applyAsposeLicense(); com.aspose.cells.Workbook asposeWorkbook = new com.aspose.cells.Workbook( new ByteArrayInputStream(excelOut.toByteArray())); PdfSaveOptions pdfOptions = new PdfSaveOptions(); pdfOptions.setOnePagePerSheet(true); pdfOptions.setAllColumnsInOnePagePerSheet(true); response.setCharacterEncoding("utf-8"); response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "inline; filename=" + new String((IcpmBusiEnum.COST_EXPORT_MAIN_PDF.getEncodedVal()).getBytes("utf-8"), "ISO8859-1")); asposeWorkbook.save(response.getOutputStream(), pdfOptions); asposeWorkbook.dispose(); } ## 任务 在输出浏览器pdf的同时调用ctrl+p调出浏览器的打印页面 ## 任务前提 1、使用的是springboot项目 2、不要改动现有代码完成任务 3、将我的输出数据转成base64Pdf然后用我给你的代码参考修改我的代码 ## 代码参考 import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Base64; @Component public class PdfPrintFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String path = httpRequest.getServletPath(); if ("/preview-main".equals(path)) { // Wrap the response to capture the PDF PdfCaptureResponseWrapper wrapper = new PdfCaptureResponseWrapper(httpResponse); chain.doFilter(request, wrapper); // Retrieve the captured PDF bytes byte[] pdfBytes = wrapper.getCapturedPdf(); // Encode the PDF to base64 for embedding String base64Pdf = Base64.getEncoder().encodeToString(pdfBytes); // Generate HTML with embedded PDF and print script String html = "<!DOCTYPE html><html><head><title>Print PDF</title></head><body>" + "<embed src=\"data:application/pdf;base64," + base64Pdf + "\" type=\"application/pdf\" width=\"100%\" height=\"100%\">" + "<script>window.onload = function() { window.print(); }</script>" + "</body></html>"; // Set the response to serve HTML httpResponse.setContentType("text/html"); httpResponse.setCharacterEncoding("UTF-8"); httpResponse.getWriter().write(html); } else { // Pass through other requests unchanged chain.doFilter(request, response); } } }

filetype
weixin_38569515
  • 粉丝: 2
上传资源 快速赚钱