@ivujs/i-utils 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +40 -42
  2. package/dist/cjs/ID-card/index.cjs +21 -13
  3. package/dist/cjs/array/index.cjs +40 -34
  4. package/dist/cjs/clipboard/index.cjs +14 -10
  5. package/dist/cjs/color/index.cjs +73 -59
  6. package/dist/cjs/cookie/index.cjs +16 -13
  7. package/dist/cjs/crypto/base64/base64.cjs +398 -206
  8. package/dist/cjs/crypto/base64/index.cjs +58 -35
  9. package/dist/cjs/crypto/md5/index.cjs +33 -8
  10. package/dist/cjs/crypto/md5/md5.cjs +298 -844
  11. package/dist/cjs/crypto/sha256/index.cjs +95 -0
  12. package/dist/cjs/crypto/sha256/sha256.cjs +557 -0
  13. package/dist/cjs/crypto/sm3/index.cjs +27 -0
  14. package/dist/cjs/crypto/sm3/sm3.cjs +200 -0
  15. package/dist/cjs/crypto/sm4/index.cjs +101 -0
  16. package/dist/cjs/crypto/sm4/sm4.cjs +498 -0
  17. package/dist/cjs/date/index.cjs +379 -335
  18. package/dist/cjs/desensitized/index.cjs +21 -18
  19. package/dist/cjs/device/index.cjs +33 -30
  20. package/dist/cjs/dom/index.cjs +26 -23
  21. package/dist/cjs/file/index.cjs +51 -41
  22. package/dist/cjs/function/index.cjs +22 -19
  23. package/dist/cjs/id/index.cjs +6 -2
  24. package/dist/cjs/index.cjs +108 -127
  25. package/dist/cjs/keycode/index.cjs +9 -12
  26. package/dist/cjs/math/index.cjs +113 -81
  27. package/dist/cjs/number/index.cjs +10 -7
  28. package/dist/cjs/object/index.cjs +77 -30
  29. package/dist/cjs/pagination/index.cjs +25 -10
  30. package/dist/cjs/random/index.cjs +8 -5
  31. package/dist/cjs/regexp/index.cjs +23 -20
  32. package/dist/cjs/storage/index.cjs +4 -1
  33. package/dist/cjs/storage/localStorage.cjs +5 -5
  34. package/dist/cjs/storage/sessionStorage.cjs +6 -6
  35. package/dist/cjs/string/index.cjs +66 -63
  36. package/dist/cjs/url/index.cjs +83 -80
  37. package/dist/cjs/validate/index.cjs +122 -106
  38. package/dist/es/ID-card/index.d.ts +19 -14
  39. package/dist/es/ID-card/index.mjs +22 -14
  40. package/dist/es/array/index.d.ts +56 -50
  41. package/dist/es/array/index.mjs +40 -34
  42. package/dist/es/clipboard/index.d.ts +10 -7
  43. package/dist/es/clipboard/index.mjs +14 -10
  44. package/dist/es/color/index.d.ts +28 -25
  45. package/dist/es/color/index.mjs +73 -59
  46. package/dist/es/constants/date.d.ts +4 -174
  47. package/dist/es/constants/id-card.d.ts +4 -43
  48. package/dist/es/constants/index.d.ts +11 -7
  49. package/dist/es/constants/keycode.d.ts +1 -103
  50. package/dist/es/constants/lang.d.ts +4 -4
  51. package/dist/es/constants/math.d.ts +4 -4
  52. package/dist/es/constants/regexp.d.ts +4 -24
  53. package/dist/es/constants/sort.d.ts +4 -5
  54. package/dist/es/cookie/index.d.ts +13 -13
  55. package/dist/es/cookie/index.mjs +16 -13
  56. package/dist/es/crypto/base64/base64.d.ts +8 -5
  57. package/dist/es/crypto/base64/base64.mjs +393 -204
  58. package/dist/es/crypto/base64/index.d.ts +41 -24
  59. package/dist/es/crypto/base64/index.mjs +53 -32
  60. package/dist/es/crypto/index.d.ts +8 -8
  61. package/dist/es/crypto/md5/index.d.ts +20 -7
  62. package/dist/es/crypto/md5/index.mjs +32 -9
  63. package/dist/es/crypto/md5/md5.d.ts +9 -142
  64. package/dist/es/crypto/md5/md5.mjs +299 -844
  65. package/dist/es/crypto/sha256/index.d.ts +52 -0
  66. package/dist/es/crypto/sha256/index.mjs +86 -0
  67. package/dist/es/crypto/sha256/sha256.d.ts +82 -0
  68. package/dist/es/crypto/sha256/sha256.mjs +548 -0
  69. package/dist/es/crypto/sm3/index.d.ts +13 -0
  70. package/dist/es/crypto/sm3/index.mjs +24 -0
  71. package/dist/es/crypto/sm3/sm3.d.ts +3 -0
  72. package/dist/es/crypto/sm3/sm3.mjs +197 -0
  73. package/dist/es/crypto/sm4/index.d.ts +56 -0
  74. package/dist/es/crypto/sm4/index.mjs +95 -0
  75. package/dist/es/crypto/sm4/sm4.d.ts +48 -0
  76. package/dist/es/crypto/sm4/sm4.mjs +490 -0
  77. package/dist/es/date/index.d.ts +236 -175
  78. package/dist/es/date/index.mjs +378 -335
  79. package/dist/es/desensitized/index.d.ts +26 -23
  80. package/dist/es/desensitized/index.mjs +21 -18
  81. package/dist/es/device/index.d.ts +31 -25
  82. package/dist/es/device/index.mjs +33 -30
  83. package/dist/es/dom/index.d.ts +32 -29
  84. package/dist/es/dom/index.mjs +26 -23
  85. package/dist/es/file/index.d.ts +30 -30
  86. package/dist/es/file/index.mjs +51 -41
  87. package/dist/es/function/index.d.ts +10 -7
  88. package/dist/es/function/index.mjs +22 -19
  89. package/dist/es/id/index.d.ts +3 -0
  90. package/dist/es/id/index.mjs +6 -2
  91. package/dist/es/index.d.ts +24 -25
  92. package/dist/es/index.mjs +6 -23
  93. package/dist/es/keycode/index.d.ts +6 -6
  94. package/dist/es/keycode/index.mjs +9 -12
  95. package/dist/es/math/index.d.ts +37 -37
  96. package/dist/es/math/index.mjs +113 -81
  97. package/dist/es/number/index.d.ts +7 -7
  98. package/dist/es/number/index.mjs +10 -7
  99. package/dist/es/object/index.d.ts +20 -19
  100. package/dist/es/object/index.mjs +77 -30
  101. package/dist/es/pagination/index.d.ts +39 -6
  102. package/dist/es/pagination/index.mjs +25 -10
  103. package/dist/es/random/index.d.ts +10 -7
  104. package/dist/es/random/index.mjs +8 -5
  105. package/dist/es/regexp/index.d.ts +30 -30
  106. package/dist/es/regexp/index.mjs +23 -20
  107. package/dist/es/storage/index.d.ts +10 -4
  108. package/dist/es/storage/index.mjs +4 -1
  109. package/dist/es/storage/localStorage.d.ts +9 -9
  110. package/dist/es/storage/localStorage.mjs +5 -5
  111. package/dist/es/storage/sessionStorage.d.ts +9 -9
  112. package/dist/es/storage/sessionStorage.mjs +6 -6
  113. package/dist/es/string/index.d.ts +62 -59
  114. package/dist/es/string/index.mjs +66 -63
  115. package/dist/es/url/index.d.ts +65 -65
  116. package/dist/es/url/index.mjs +83 -80
  117. package/dist/es/validate/index.d.ts +83 -80
  118. package/dist/es/validate/index.mjs +122 -106
  119. package/dist/index.d.ts +2355 -2803
  120. package/dist/lib/index.full.umd.js +3297 -9474
  121. package/dist/lib/index.full.umd.min.js +2 -64
  122. package/dist/lib/index.full.umd.min.js.map +1 -1
  123. package/dist/resolver/auto-imports.cjs +38 -31
  124. package/dist/resolver/auto-imports.mjs +38 -31
  125. package/dist/resolver/index.cjs +1 -2
  126. package/dist/resolver/index.d.ts +1 -1
  127. package/dist/resolver/index.mjs +1 -2
  128. package/package.json +96 -90
  129. package/dist/cjs/crypto/aes/aes.cjs +0 -480
  130. package/dist/cjs/crypto/aes/index.cjs +0 -27
  131. package/dist/cjs/crypto/base32/base32.cjs +0 -357
  132. package/dist/cjs/crypto/base32/index.cjs +0 -41
  133. package/dist/cjs/crypto/des/des.cjs +0 -257
  134. package/dist/cjs/crypto/des/index.cjs +0 -28
  135. package/dist/cjs/crypto/sha/sha1/index.cjs +0 -24
  136. package/dist/cjs/crypto/sha/sha1/sha1.cjs +0 -529
  137. package/dist/cjs/crypto/sha/sha256/index.cjs +0 -43
  138. package/dist/cjs/crypto/sha/sha256/sha256.cjs +0 -595
  139. package/dist/cjs/crypto/sha/sha3/index.cjs +0 -41
  140. package/dist/cjs/crypto/sha/sha3/sha3.cjs +0 -624
  141. package/dist/cjs/crypto/sha/sha512/index.cjs +0 -81
  142. package/dist/cjs/crypto/sha/sha512/sha512.cjs +0 -950
  143. package/dist/cjs/crypto/sm/lib/asn1.cjs +0 -149
  144. package/dist/cjs/crypto/sm/lib/ec.cjs +0 -315
  145. package/dist/cjs/crypto/sm/lib/jsbn.cjs +0 -1608
  146. package/dist/cjs/crypto/sm/lib/sm3.cjs +0 -158
  147. package/dist/cjs/crypto/sm/lib/utils.cjs +0 -170
  148. package/dist/cjs/crypto/sm/sm2/index.cjs +0 -112
  149. package/dist/cjs/crypto/sm/sm2/sm2.cjs +0 -231
  150. package/dist/cjs/crypto/sm/sm3/index.cjs +0 -15
  151. package/dist/cjs/crypto/sm/sm3/sm3.cjs +0 -93
  152. package/dist/cjs/crypto/sm/sm4/index.cjs +0 -27
  153. package/dist/cjs/crypto/sm/sm4/sm4.cjs +0 -327
  154. package/dist/cjs/crypto/tea/index.cjs +0 -25
  155. package/dist/cjs/crypto/tea/tea.cjs +0 -187
  156. package/dist/cjs/weapp/index.cjs +0 -142
  157. package/dist/es/crypto/aes/aes.d.ts +0 -156
  158. package/dist/es/crypto/aes/aes.mjs +0 -478
  159. package/dist/es/crypto/aes/index.d.ts +0 -16
  160. package/dist/es/crypto/aes/index.mjs +0 -24
  161. package/dist/es/crypto/base32/base32.d.ts +0 -3
  162. package/dist/es/crypto/base32/base32.mjs +0 -353
  163. package/dist/es/crypto/base32/index.d.ts +0 -24
  164. package/dist/es/crypto/base32/index.mjs +0 -36
  165. package/dist/es/crypto/des/des.d.ts +0 -52
  166. package/dist/es/crypto/des/des.mjs +0 -255
  167. package/dist/es/crypto/des/index.d.ts +0 -14
  168. package/dist/es/crypto/des/index.mjs +0 -25
  169. package/dist/es/crypto/sha/index.d.ts +0 -4
  170. package/dist/es/crypto/sha/sha1/index.d.ts +0 -13
  171. package/dist/es/crypto/sha/sha1/index.mjs +0 -21
  172. package/dist/es/crypto/sha/sha1/sha1.d.ts +0 -2
  173. package/dist/es/crypto/sha/sha1/sha1.mjs +0 -526
  174. package/dist/es/crypto/sha/sha256/index.d.ts +0 -26
  175. package/dist/es/crypto/sha/sha256/index.mjs +0 -38
  176. package/dist/es/crypto/sha/sha256/sha256.d.ts +0 -4
  177. package/dist/es/crypto/sha/sha256/sha256.mjs +0 -590
  178. package/dist/es/crypto/sha/sha3/index.d.ts +0 -24
  179. package/dist/es/crypto/sha/sha3/index.mjs +0 -36
  180. package/dist/es/crypto/sha/sha3/sha3.d.ts +0 -4
  181. package/dist/es/crypto/sha/sha3/sha3.mjs +0 -619
  182. package/dist/es/crypto/sha/sha512/index.d.ts +0 -52
  183. package/dist/es/crypto/sha/sha512/index.mjs +0 -72
  184. package/dist/es/crypto/sha/sha512/sha512.d.ts +0 -8
  185. package/dist/es/crypto/sha/sha512/sha512.mjs +0 -941
  186. package/dist/es/crypto/sm/index.d.ts +0 -3
  187. package/dist/es/crypto/sm/lib/asn1.d.ts +0 -12
  188. package/dist/es/crypto/sm/lib/asn1.mjs +0 -146
  189. package/dist/es/crypto/sm/lib/ec.d.ts +0 -126
  190. package/dist/es/crypto/sm/lib/ec.mjs +0 -312
  191. package/dist/es/crypto/sm/lib/jsbn.d.ts +0 -198
  192. package/dist/es/crypto/sm/lib/jsbn.mjs +0 -1605
  193. package/dist/es/crypto/sm/lib/sm3.d.ts +0 -5
  194. package/dist/es/crypto/sm/lib/sm3.mjs +0 -155
  195. package/dist/es/crypto/sm/lib/utils.d.ts +0 -53
  196. package/dist/es/crypto/sm/lib/utils.mjs +0 -158
  197. package/dist/es/crypto/sm/sm2/index.d.ts +0 -71
  198. package/dist/es/crypto/sm/sm2/index.mjs +0 -101
  199. package/dist/es/crypto/sm/sm2/sm2.d.ts +0 -34
  200. package/dist/es/crypto/sm/sm2/sm2.mjs +0 -220
  201. package/dist/es/crypto/sm/sm3/index.d.ts +0 -7
  202. package/dist/es/crypto/sm/sm3/index.mjs +0 -13
  203. package/dist/es/crypto/sm/sm3/sm3.d.ts +0 -1
  204. package/dist/es/crypto/sm/sm3/sm3.mjs +0 -91
  205. package/dist/es/crypto/sm/sm4/index.d.ts +0 -16
  206. package/dist/es/crypto/sm/sm4/index.mjs +0 -24
  207. package/dist/es/crypto/sm/sm4/sm4.d.ts +0 -2
  208. package/dist/es/crypto/sm/sm4/sm4.mjs +0 -324
  209. package/dist/es/crypto/tea/index.d.ts +0 -14
  210. package/dist/es/crypto/tea/index.mjs +0 -22
  211. package/dist/es/crypto/tea/tea.d.ts +0 -69
  212. package/dist/es/crypto/tea/tea.mjs +0 -185
  213. package/dist/es/weapp/index.d.ts +0 -57
  214. package/dist/es/weapp/index.mjs +0 -131
@@ -1,209 +1,273 @@
1
1
  'use strict';
2
2
 
3
3
  /*
4
- * [hi-base64]{@link https://github.com/emn178/hi-base64}
5
- *
6
- * @version 0.3.1
7
- * @author Chen, Yi-Cyuan [emn178@gmail.com]
8
- * @copyright Chen, Yi-Cyuan 2014-2023
9
- * @license MIT
4
+ * base64加解密
5
+ * 高性能、高健壮性、纯JS实现,兼容Node/浏览器/Worker
10
6
  */
11
- /* jslint bitwise: true */
12
- var ENCODING_ERROR = "not a UTF-8 string";
13
- var WINDOW = typeof window === "object";
14
- var root = WINDOW ? window : {};
15
- if (root.HI_BASE64_NO_WINDOW) {
16
- WINDOW = false;
17
- }
18
- var WEB_WORKER = !WINDOW && typeof self === "object";
19
- var NODE_JS = !root.HI_BASE64_NO_NODE_JS && typeof process === "object" && process.versions && process.versions.node;
20
- if (NODE_JS) {
21
- root = global;
22
- }
23
- else if (WEB_WORKER) {
24
- root = self;
25
- }
26
- var BASE64_ENCODE_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
27
- var BASE64_DECODE_CHAR = {};
28
- for (var i = 0; i < 64; ++i) {
7
+ // 核心常量定义
8
+ const ENCODING_ERROR = "not a UTF-8 string";
9
+ const BASE64_ENCODE_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
10
+ const BASE64_DECODE_CHAR = {};
11
+ for (let i = 0; i < 64; ++i) {
29
12
  BASE64_DECODE_CHAR[BASE64_ENCODE_CHAR[i]] = i;
30
13
  }
14
+ // 兼容URL安全的Base64
31
15
  BASE64_DECODE_CHAR["-"] = 62;
32
16
  BASE64_DECODE_CHAR["_"] = 63;
33
- var cleanBase64Str = function (base64Str) {
34
- return base64Str.split("=")[0].replace(/[\r\n]/g, "");
17
+ // ======================== 精简版环境判断(核心场景全覆盖,保留!)========================
18
+ const isNodeEnv = typeof process === "object" && process.versions && process.versions.node;
19
+ const isBrowserEnv = typeof window === "object" && typeof window.btoa === "function";
20
+ const root = isNodeEnv ? global : typeof self === "object" ? self : window;
21
+ // ======================== 核心工具函数(全部保留,原生API更快!)========================
22
+ /**
23
+ * 清理Base64字符串(移除等号、换行符、非法字符)
24
+ */
25
+ const cleanBase64Str = function (base64Str) {
26
+ return base64Str
27
+ .split("=")[0]
28
+ .replace(/[\r\n]/g, "")
29
+ .replace(/[^A-Za-z0-9+/=_-]/g, ""); // 过滤非法字符
35
30
  };
36
- var utf8ToBytes = function (str) {
37
- var bytes = [];
38
- for (var i = 0; i < str.length; i++) {
39
- var c = str.charCodeAt(i);
31
+ /**
32
+ * UTF-8字符串转字节数组(性能优化版)
33
+ */
34
+ const utf8ToBytes = function (str) {
35
+ const len = str.length; // 缓存长度,减少属性访问
36
+ const bytes = new Array(len * 4); // 预分配最大可能长度(避免频繁扩容)
37
+ let byteIndex = 0;
38
+ for (let i = 0; i < len; i++) {
39
+ const c = str.charCodeAt(i);
40
40
  if (c < 0x80) {
41
- bytes[bytes.length] = c;
41
+ bytes[byteIndex++] = c;
42
42
  }
43
43
  else if (c < 0x800) {
44
- bytes[bytes.length] = 0xc0 | (c >> 6);
45
- bytes[bytes.length] = 0x80 | (c & 0x3f);
44
+ bytes[byteIndex++] = 0xc0 | (c >> 6);
45
+ bytes[byteIndex++] = 0x80 | (c & 0x3f);
46
46
  }
47
47
  else if (c < 0xd800 || c >= 0xe000) {
48
- bytes[bytes.length] = 0xe0 | (c >> 12);
49
- bytes[bytes.length] = 0x80 | ((c >> 6) & 0x3f);
50
- bytes[bytes.length] = 0x80 | (c & 0x3f);
48
+ bytes[byteIndex++] = 0xe0 | (c >> 12);
49
+ bytes[byteIndex++] = 0x80 | ((c >> 6) & 0x3f);
50
+ bytes[byteIndex++] = 0x80 | (c & 0x3f);
51
51
  }
52
52
  else {
53
- c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
54
- bytes[bytes.length] = 0xf0 | (c >> 18);
55
- bytes[bytes.length] = 0x80 | ((c >> 12) & 0x3f);
56
- bytes[bytes.length] = 0x80 | ((c >> 6) & 0x3f);
57
- bytes[bytes.length] = 0x80 | (c & 0x3f);
53
+ // 处理代理对
54
+ const code = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
55
+ bytes[byteIndex++] = 0xf0 | (code >> 18);
56
+ bytes[byteIndex++] = 0x80 | ((code >> 12) & 0x3f);
57
+ bytes[byteIndex++] = 0x80 | ((code >> 6) & 0x3f);
58
+ bytes[byteIndex++] = 0x80 | (code & 0x3f);
58
59
  }
59
60
  }
60
- return bytes;
61
+ // 截断数组到实际长度
62
+ return bytes.slice(0, byteIndex);
61
63
  };
62
- var decodeAsBytes = function (base64Str) {
64
+ /**
65
+ * Base64字符串解码为字节数组(性能优化版)
66
+ */
67
+ const decodeAsBytes = function (base64Str) {
68
+ // 空值快速返回
69
+ if (!base64Str)
70
+ return [];
63
71
  base64Str = cleanBase64Str(base64Str);
64
- var v1, v2, v3, v4, bytes = [], index = 0, length = base64Str.length;
65
- // 4 char to 3 bytes
66
- for (var i = 0, count = (length >> 2) << 2; i < count;) {
67
- v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
68
- v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
69
- v3 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
70
- v4 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
71
- bytes[index++] = ((v1 << 2) | (v2 >>> 4)) & 255;
72
- bytes[index++] = ((v2 << 4) | (v3 >>> 2)) & 255;
73
- bytes[index++] = ((v3 << 6) | v4) & 255;
72
+ const len = base64Str.length;
73
+ const count = (len >> 2) << 2;
74
+ // 预计算最大长度:3/4 * 总字符数,减少数组扩容
75
+ const bytes = new Array(Math.floor((len * 3) / 4));
76
+ let byteIndex = 0;
77
+ let i = 0; // 把i的作用域提升到函数级,确保后续能访问
78
+ // 4字符转3字节
79
+ for (; i < count;) {
80
+ const v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
81
+ const v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
82
+ const v3 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
83
+ const v4 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
84
+ bytes[byteIndex++] = ((v1 << 2) | (v2 >>> 4)) & 255;
85
+ bytes[byteIndex++] = ((v2 << 4) | (v3 >>> 2)) & 255;
86
+ bytes[byteIndex++] = ((v3 << 6) | v4) & 255;
74
87
  }
75
- // remain bytes
76
- var remain = length - count;
88
+ // 处理剩余字符(此时i的作用域有效)
89
+ const remain = len - count;
77
90
  if (remain === 2) {
78
- v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
79
- v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
80
- bytes[index++] = ((v1 << 2) | (v2 >>> 4)) & 255;
91
+ const v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
92
+ const v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
93
+ bytes[byteIndex++] = ((v1 << 2) | (v2 >>> 4)) & 255;
81
94
  }
82
95
  else if (remain === 3) {
83
- v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
84
- v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
85
- v3 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
86
- bytes[index++] = ((v1 << 2) | (v2 >>> 4)) & 255;
87
- bytes[index++] = ((v2 << 4) | (v3 >>> 2)) & 255;
96
+ const v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
97
+ const v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
98
+ const v3 = BASE64_DECODE_CHAR[base64Str.charAt(i++)] || 0;
99
+ bytes[byteIndex++] = ((v1 << 2) | (v2 >>> 4)) & 255;
100
+ bytes[byteIndex++] = ((v2 << 4) | (v3 >>> 2)) & 255;
88
101
  }
89
- return bytes;
102
+ // 截断数组到实际长度
103
+ return bytes.slice(0, byteIndex);
90
104
  };
91
- var encodeFromBytes = function (bytes) {
92
- var v1, v2, v3, base64Str = [], length = bytes.length;
93
- for (var i = 0, count = parseInt(length / 3) * 3; i < count;) {
94
- v1 = bytes[i++];
95
- v2 = bytes[i++];
96
- v3 = bytes[i++];
97
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63], BASE64_ENCODE_CHAR[((v2 << 2) | (v3 >>> 6)) & 63], BASE64_ENCODE_CHAR[v3 & 63]);
105
+ /**
106
+ * 抽离公共逻辑:字节数组转Base64字符(减少代码冗余)
107
+ */
108
+ const bytesToBase64Chars = function (bytes) {
109
+ const len = bytes.length;
110
+ const count = Math.floor(len / 3) * 3;
111
+ const base64Str = new Array(Math.ceil((len * 4) / 3)); // 预分配长度
112
+ let strIndex = 0;
113
+ // 3字节转4字符
114
+ for (let i = 0; i < count;) {
115
+ const v1 = bytes[i++];
116
+ const v2 = bytes[i++];
117
+ const v3 = bytes[i++];
118
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[v1 >>> 2];
119
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63];
120
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[((v2 << 2) | (v3 >>> 6)) & 63];
121
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[v3 & 63];
98
122
  }
99
- // remain char
100
- var remain = length - count;
123
+ // 处理剩余字节
124
+ const remain = len - count;
101
125
  if (remain === 1) {
102
- v1 = bytes[i];
103
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[(v1 << 4) & 63], "==");
126
+ const v1 = bytes[count];
127
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[v1 >>> 2];
128
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[(v1 << 4) & 63];
129
+ base64Str[strIndex++] = "=";
130
+ base64Str[strIndex++] = "=";
104
131
  }
105
132
  else if (remain === 2) {
106
- v1 = bytes[i++];
107
- v2 = bytes[i];
108
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63], BASE64_ENCODE_CHAR[(v2 << 2) & 63], "=");
133
+ const v1 = bytes[count];
134
+ const v2 = bytes[count + 1];
135
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[v1 >>> 2];
136
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63];
137
+ base64Str[strIndex++] = BASE64_ENCODE_CHAR[(v2 << 2) & 63];
138
+ base64Str[strIndex++] = "=";
109
139
  }
110
140
  return base64Str.join("");
111
141
  };
112
- var btoa = root.btoa, atob = root.atob, utf8Base64Encode, utf8Base64Decode;
113
- if (NODE_JS) {
114
- var Buffer = require("buffer").Buffer;
142
+ /**
143
+ * 字节数组编码为Base64字符串(复用公共逻辑)
144
+ */
145
+ let encodeFromBytes = function (bytes) {
146
+ // 空值快速返回
147
+ if (!bytes || bytes.length === 0)
148
+ return "";
149
+ return bytesToBase64Chars(bytes);
150
+ };
151
+ // ======================== 环境适配的btoa/atob实现(全部保留,原生更快!)=======================
152
+ let btoa = root.btoa;
153
+ let atob = root.atob;
154
+ let utf8Base64Encode;
155
+ let utf8Base64Decode;
156
+ // 1. Node.js环境(纯JS实现,不使用require)
157
+ if (isNodeEnv) {
158
+ // 纯JS版btoa(替代Buffer实现)
115
159
  btoa = function (str) {
116
- return Buffer.from(str, "ascii").toString("base64");
160
+ if (!str)
161
+ return "";
162
+ const bytes = Array.from(str).map((c) => c.charCodeAt(0));
163
+ return bytesToBase64Chars(bytes);
117
164
  };
118
- utf8Base64Encode = function (str) {
119
- return Buffer.from(str).toString("base64");
120
- };
121
- encodeFromBytes = utf8Base64Encode;
165
+ // 纯JS版atob
122
166
  atob = function (base64Str) {
123
- return Buffer.from(base64Str, "base64").toString("ascii");
167
+ if (!base64Str)
168
+ return "";
169
+ const bytes = decodeAsBytes(base64Str);
170
+ return String.fromCharCode.apply(null, bytes);
171
+ };
172
+ // 纯JS版UTF8编码/解码(和浏览器环境保持一致)
173
+ utf8Base64Encode = function (str) {
174
+ if (!str)
175
+ return "";
176
+ const bytes = utf8ToBytes(str);
177
+ return bytesToBase64Chars(bytes);
124
178
  };
125
179
  utf8Base64Decode = function (base64Str) {
126
- return Buffer.from(base64Str, "base64").toString();
180
+ if (!base64Str)
181
+ return "";
182
+ const bytes = decodeAsBytes(base64Str);
183
+ const str = [];
184
+ const len = bytes.length;
185
+ let i = 0;
186
+ while (i < len) {
187
+ const b = bytes[i++];
188
+ if (b <= 0x7f) {
189
+ str.push(String.fromCharCode(b));
190
+ continue;
191
+ }
192
+ let c, followingChars;
193
+ if (b > 0xbf && b <= 0xdf) {
194
+ c = b & 0x1f;
195
+ followingChars = 1;
196
+ }
197
+ else if (b <= 0xef) {
198
+ c = b & 0x0f;
199
+ followingChars = 2;
200
+ }
201
+ else if (b <= 0xf7) {
202
+ c = b & 0x07;
203
+ followingChars = 3;
204
+ }
205
+ else {
206
+ throw new Error(ENCODING_ERROR);
207
+ }
208
+ // 校验后续字节合法性
209
+ for (let j = 0; j < followingChars; ++j) {
210
+ const byte = bytes[i++];
211
+ if (i > len || byte < 0x80 || byte > 0xbf) {
212
+ throw new Error(ENCODING_ERROR);
213
+ }
214
+ c = (c << 6) + (byte & 0x3f);
215
+ }
216
+ // 校验Unicode范围
217
+ if (c >= 0xd800 && c <= 0xdfff)
218
+ throw new Error(ENCODING_ERROR);
219
+ if (c > 0x10ffff)
220
+ throw new Error(ENCODING_ERROR);
221
+ // 转换为字符
222
+ if (c <= 0xffff) {
223
+ str.push(String.fromCharCode(c));
224
+ }
225
+ else {
226
+ c -= 0x10000;
227
+ str.push(String.fromCharCode((c >> 10) + 0xd800), String.fromCharCode((c & 0x3ff) + 0xdc00));
228
+ }
229
+ }
230
+ return str.join("");
127
231
  };
232
+ // 2. 无原生btoa/atob的环境(老旧浏览器/Worker)
128
233
  }
129
- else if (!btoa) {
234
+ else if (!isBrowserEnv) {
235
+ // 纯JS版btoa(复用公共逻辑)
130
236
  btoa = function (str) {
131
- var v1, v2, v3, base64Str = [], length = str.length;
132
- for (var i = 0, count = parseInt(length / 3) * 3; i < count;) {
133
- v1 = str.charCodeAt(i++);
134
- v2 = str.charCodeAt(i++);
135
- v3 = str.charCodeAt(i++);
136
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63], BASE64_ENCODE_CHAR[((v2 << 2) | (v3 >>> 6)) & 63], BASE64_ENCODE_CHAR[v3 & 63]);
137
- }
138
- // remain char
139
- var remain = length - count;
140
- if (remain === 1) {
141
- v1 = str.charCodeAt(i);
142
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[(v1 << 4) & 63], "==");
143
- }
144
- else if (remain === 2) {
145
- v1 = str.charCodeAt(i++);
146
- v2 = str.charCodeAt(i);
147
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63], BASE64_ENCODE_CHAR[(v2 << 2) & 63], "=");
148
- }
149
- return base64Str.join("");
150
- };
151
- utf8Base64Encode = function (str) {
152
- var v1, v2, v3, base64Str = [], bytes = utf8ToBytes(str), length = bytes.length;
153
- for (var i = 0, count = parseInt(length / 3) * 3; i < count;) {
154
- v1 = bytes[i++];
155
- v2 = bytes[i++];
156
- v3 = bytes[i++];
157
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63], BASE64_ENCODE_CHAR[((v2 << 2) | (v3 >>> 6)) & 63], BASE64_ENCODE_CHAR[v3 & 63]);
158
- }
159
- // remain char
160
- var remain = length - count;
161
- if (remain === 1) {
162
- v1 = bytes[i];
163
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[(v1 << 4) & 63], "==");
164
- }
165
- else if (remain === 2) {
166
- v1 = bytes[i++];
167
- v2 = bytes[i];
168
- base64Str.push(BASE64_ENCODE_CHAR[v1 >>> 2], BASE64_ENCODE_CHAR[((v1 << 4) | (v2 >>> 4)) & 63], BASE64_ENCODE_CHAR[(v2 << 2) & 63], "=");
169
- }
170
- return base64Str.join("");
237
+ if (!str)
238
+ return "";
239
+ const bytes = Array.from(str).map((c) => c.charCodeAt(0));
240
+ return bytesToBase64Chars(bytes);
171
241
  };
242
+ // 纯JS版atob
172
243
  atob = function (base64Str) {
173
- var v1, v2, v3, v4, str = [], length = base64Str.length;
174
- // 4 char to 3 bytes
175
- for (var i = 0, count = (length >> 2) << 2; i < count;) {
176
- v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
177
- v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
178
- v3 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
179
- v4 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
180
- str.push(String.fromCharCode(((v1 << 2) | (v2 >>> 4)) & 255), String.fromCharCode(((v2 << 4) | (v3 >>> 2)) & 255), String.fromCharCode(((v3 << 6) | v4) & 255));
181
- }
182
- // remain bytes
183
- var remain = length - count;
184
- if (remain === 2) {
185
- v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
186
- v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
187
- str.push(String.fromCharCode(((v1 << 2) | (v2 >>> 4)) & 255));
188
- }
189
- else if (remain === 3) {
190
- v1 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
191
- v2 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
192
- v3 = BASE64_DECODE_CHAR[base64Str.charAt(i++)];
193
- str.push(String.fromCharCode(((v1 << 2) | (v2 >>> 4)) & 255), String.fromCharCode(((v2 << 4) | (v3 >>> 2)) & 255));
194
- }
195
- return str.join("");
244
+ if (!base64Str)
245
+ return "";
246
+ const bytes = decodeAsBytes(base64Str);
247
+ return String.fromCharCode.apply(null, bytes);
248
+ };
249
+ // 纯JS版UTF8编码/解码
250
+ utf8Base64Encode = function (str) {
251
+ if (!str)
252
+ return "";
253
+ const bytes = utf8ToBytes(str);
254
+ return bytesToBase64Chars(bytes);
196
255
  };
197
256
  utf8Base64Decode = function (base64Str) {
198
- var str = [], bytes = decodeAsBytes(base64Str), length = bytes.length;
199
- var i = 0, followingChars = 0, b, c;
200
- while (i < length) {
201
- b = bytes[i++];
257
+ if (!base64Str)
258
+ return "";
259
+ const bytes = decodeAsBytes(base64Str);
260
+ const str = [];
261
+ const len = bytes.length;
262
+ let i = 0;
263
+ while (i < len) {
264
+ const b = bytes[i++];
202
265
  if (b <= 0x7f) {
203
266
  str.push(String.fromCharCode(b));
204
267
  continue;
205
268
  }
206
- else if (b > 0xbf && b <= 0xdf) {
269
+ let c, followingChars;
270
+ if (b > 0xbf && b <= 0xdf) {
207
271
  c = b & 0x1f;
208
272
  followingChars = 1;
209
273
  }
@@ -218,20 +282,20 @@ else if (!btoa) {
218
282
  else {
219
283
  throw new Error(ENCODING_ERROR);
220
284
  }
221
- for (var j = 0; j < followingChars; ++j) {
222
- b = bytes[i++];
223
- if (b < 0x80 || b > 0xbf) {
285
+ // 校验后续字节合法性
286
+ for (let j = 0; j < followingChars; ++j) {
287
+ const byte = bytes[i++];
288
+ if (i > len || byte < 0x80 || byte > 0xbf) {
224
289
  throw new Error(ENCODING_ERROR);
225
290
  }
226
- c <<= 6;
227
- c += b & 0x3f;
291
+ c = (c << 6) + (byte & 0x3f);
228
292
  }
229
- if (c >= 0xd800 && c <= 0xdfff) {
293
+ // 校验Unicode范围
294
+ if (c >= 0xd800 && c <= 0xdfff)
230
295
  throw new Error(ENCODING_ERROR);
231
- }
232
- if (c > 0x10ffff) {
296
+ if (c > 0x10ffff)
233
297
  throw new Error(ENCODING_ERROR);
234
- }
298
+ // 转换为字符
235
299
  if (c <= 0xffff) {
236
300
  str.push(String.fromCharCode(c));
237
301
  }
@@ -242,12 +306,16 @@ else if (!btoa) {
242
306
  }
243
307
  return str.join("");
244
308
  };
309
+ // 3. 浏览器原生支持btoa/atob
245
310
  }
246
311
  else {
247
312
  utf8Base64Encode = function (str) {
248
- var result = [];
249
- for (var i = 0; i < str.length; i++) {
250
- var charcode = str.charCodeAt(i);
313
+ if (!str)
314
+ return "";
315
+ const result = [];
316
+ const len = str.length;
317
+ for (let i = 0; i < len; i++) {
318
+ const charcode = str.charCodeAt(i);
251
319
  if (charcode < 0x80) {
252
320
  result.push(String.fromCharCode(charcode));
253
321
  }
@@ -258,25 +326,32 @@ else {
258
326
  result.push(String.fromCharCode(0xe0 | (charcode >> 12)), String.fromCharCode(0x80 | ((charcode >> 6) & 0x3f)), String.fromCharCode(0x80 | (charcode & 0x3f)));
259
327
  }
260
328
  else {
261
- charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
262
- result.push(String.fromCharCode(0xf0 | (charcode >> 18)), String.fromCharCode(0x80 | ((charcode >> 12) & 0x3f)), String.fromCharCode(0x80 | ((charcode >> 6) & 0x3f)), String.fromCharCode(0x80 | (charcode & 0x3f)));
329
+ const code = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
330
+ result.push(String.fromCharCode(0xf0 | (code >> 18)), String.fromCharCode(0x80 | ((code >> 12) & 0x3f)), String.fromCharCode(0x80 | ((code >> 6) & 0x3f)), String.fromCharCode(0x80 | (code & 0x3f)));
263
331
  }
264
332
  }
265
333
  return btoa(result.join(""));
266
334
  };
267
335
  utf8Base64Decode = function (base64Str) {
268
- var tmpStr = atob(base64Str.replace(/-/g, "+").replace(/_/g, "/"));
269
- if (!/[^\x00-\x7F]/.test(tmpStr)) {
336
+ if (!base64Str)
337
+ return "";
338
+ const tmpStr = atob(base64Str.replace(/-/g, "+").replace(/_/g, "/"));
339
+ // 替换Unicode转义,避免ESLint控制字符警告
340
+ // eslint-disable-next-line no-control-regex
341
+ if (!/[^\u0000-\u007F]/.test(tmpStr)) {
270
342
  return tmpStr;
271
343
  }
272
- var str = [], i = 0, length = tmpStr.length, followingChars = 0, b, c;
273
- while (i < length) {
274
- b = tmpStr.charCodeAt(i++);
344
+ const str = [];
345
+ const len = tmpStr.length;
346
+ let i = 0;
347
+ while (i < len) {
348
+ const b = tmpStr.charCodeAt(i++);
275
349
  if (b <= 0x7f) {
276
350
  str.push(String.fromCharCode(b));
277
351
  continue;
278
352
  }
279
- else if (b > 0xbf && b <= 0xdf) {
353
+ let c, followingChars;
354
+ if (b > 0xbf && b <= 0xdf) {
280
355
  c = b & 0x1f;
281
356
  followingChars = 1;
282
357
  }
@@ -291,20 +366,16 @@ else {
291
366
  else {
292
367
  throw new Error(ENCODING_ERROR);
293
368
  }
294
- for (var j = 0; j < followingChars; ++j) {
295
- b = tmpStr.charCodeAt(i++);
296
- if (b < 0x80 || b > 0xbf) {
369
+ for (let j = 0; j < followingChars; ++j) {
370
+ const byte = tmpStr.charCodeAt(i++);
371
+ if (i > len || byte < 0x80 || byte > 0xbf)
297
372
  throw new Error(ENCODING_ERROR);
298
- }
299
- c <<= 6;
300
- c += b & 0x3f;
373
+ c = (c << 6) + (byte & 0x3f);
301
374
  }
302
- if (c >= 0xd800 && c <= 0xdfff) {
375
+ if (c >= 0xd800 && c <= 0xdfff)
303
376
  throw new Error(ENCODING_ERROR);
304
- }
305
- if (c > 0x10ffff) {
377
+ if (c > 0x10ffff)
306
378
  throw new Error(ENCODING_ERROR);
307
- }
308
379
  if (c <= 0xffff) {
309
380
  str.push(String.fromCharCode(c));
310
381
  }
@@ -316,33 +387,154 @@ else {
316
387
  return str.join("");
317
388
  };
318
389
  }
319
- var encode = function (str, asciiOnly) {
320
- var notString = typeof str != "string";
321
- if (notString && str.constructor === root.ArrayBuffer) {
322
- str = new Uint8Array(str);
390
+ // ======================== 类型转换工具函数(全部保留)========================
391
+ /**
392
+ * Uint8Array转Base64字符串
393
+ * @param {Uint8Array} uint8Array 字节数组
394
+ * @param {boolean} [urlSafe=false] 是否URL安全
395
+ * @returns {string} Base64字符串
396
+ */
397
+ const fromUint8Array = function (uint8Array, urlSafe = false) {
398
+ if (!(uint8Array instanceof Uint8Array)) {
399
+ throw new TypeError("fromUint8Array方法仅支持Uint8Array输入");
400
+ }
401
+ const bytes = Array.from(uint8Array);
402
+ let result = bytesToBase64Chars(bytes);
403
+ if (urlSafe) {
404
+ result = result.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
405
+ }
406
+ return result;
407
+ };
408
+ /**
409
+ * Base64字符串转Uint8Array
410
+ * @param {string} base64Str Base64字符串
411
+ * @param {boolean} [urlSafe=false] 是否URL安全
412
+ * @returns {Uint8Array} 字节数组
413
+ */
414
+ const toUint8Array = function (base64Str, urlSafe = false) {
415
+ if (typeof base64Str !== "string") {
416
+ throw new TypeError("toUint8Array方法仅支持字符串输入");
323
417
  }
418
+ // 处理URL安全字符
419
+ if (urlSafe) {
420
+ base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
421
+ }
422
+ const bytes = decodeAsBytes(base64Str);
423
+ return new Uint8Array(bytes);
424
+ };
425
+ /**
426
+ * 十六进制字符串转Base64字符串
427
+ * @param {string} hexStr 十六进制字符串
428
+ * @param {boolean} [urlSafe=false] 是否URL安全
429
+ * @returns {string} Base64字符串
430
+ */
431
+ const fromHex = function (hexStr, urlSafe = false) {
432
+ if (typeof hexStr !== "string" || !/^[0-9a-fA-F]+$/.test(hexStr)) {
433
+ throw new TypeError("fromHex方法仅支持十六进制字符串输入");
434
+ }
435
+ // 补全偶数长度
436
+ const str = hexStr.length % 2 ? `0${hexStr}` : hexStr;
437
+ const bytes = new Array(str.length / 2);
438
+ for (let i = 0; i < bytes.length; i++) {
439
+ bytes[i] = parseInt(str.substr(i * 2, 2), 16);
440
+ }
441
+ let result = bytesToBase64Chars(bytes);
442
+ if (urlSafe) {
443
+ result = result.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
444
+ }
445
+ return result;
446
+ };
447
+ /**
448
+ * Base64字符串转十六进制字符串
449
+ * @param {string} base64Str Base64字符串
450
+ * @param {boolean} [urlSafe=false] 是否URL安全
451
+ * @returns {string} 十六进制字符串
452
+ */
453
+ const toHex = function (base64Str, urlSafe = false) {
454
+ if (typeof base64Str !== "string") {
455
+ throw new TypeError("toHex方法仅支持字符串输入");
456
+ }
457
+ // 处理URL安全字符
458
+ if (urlSafe) {
459
+ base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
460
+ }
461
+ const bytes = decodeAsBytes(base64Str);
462
+ return Array.from(bytes)
463
+ .map((byte) => byte.toString(16).padStart(2, "0"))
464
+ .join("");
465
+ };
466
+ // ======================== 核心方法(仅删除asciiOnly开关,默认UTF8)========================
467
+ /**
468
+ * Base64编码(高性能、高健壮性版,默认UTF8)
469
+ * @param {string | number[] | Uint8Array | ArrayBuffer} data 待编码数据
470
+ * @param {boolean} [urlSafe=false] 是否生成URL安全的Base64
471
+ * @returns {string} Base64字符串
472
+ */
473
+ const encode = function (data, urlSafe = false) {
474
+ // 空值快速返回
475
+ if (data == null)
476
+ return "";
477
+ const notString = typeof data !== "string";
478
+ let result = "";
324
479
  if (notString) {
325
- return encodeFromBytes(str);
480
+ // 处理ArrayBuffer
481
+ if (data.constructor === root.ArrayBuffer) {
482
+ data = new Uint8Array(data);
483
+ }
484
+ // 处理字节数组/Uint8Array
485
+ result = encodeFromBytes(data);
326
486
  }
327
487
  else {
328
- if (/[^\x00-\x7F]/.test(str)) {
329
- return utf8Base64Encode(str);
330
- }
331
- else {
332
- return btoa(str);
333
- }
488
+ // 空字符串快速返回
489
+ if (data === "")
490
+ return "";
491
+ // 强制走UTF8编码(删掉asciiOnly判断,直接用utf8Base64Encode)
492
+ result = utf8Base64Encode(data);
493
+ }
494
+ // URL安全处理:替换+->-,/->_,去掉=
495
+ if (urlSafe) {
496
+ result = result.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
334
497
  }
498
+ return result;
335
499
  };
336
- var decode = function (base64Str, asciiOnly) {
500
+ /**
501
+ * Base64解码(高性能、高健壮性版,默认UTF8)
502
+ * @param {string} base64Str 待解码的Base64字符串
503
+ * @returns {string} 解码后的UTF8字符串
504
+ */
505
+ const decode = function (base64Str) {
506
+ // 空值快速返回
507
+ if (base64Str == null || base64Str === "")
508
+ return "";
509
+ // 处理URL安全的Base64
510
+ base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
337
511
  base64Str = cleanBase64Str(base64Str);
338
- return asciiOnly ? atob(base64Str) : utf8Base64Decode(base64Str);
512
+ // 强制走UTF8解码(删掉asciiOnly判断,直接用utf8Base64Decode
513
+ return utf8Base64Decode(base64Str);
514
+ };
515
+ // ======================== URL安全专用方法(同步删除asciiOnly开关)========================
516
+ /**
517
+ * URL安全Base64编码(专用方法,等价于encode(data, true))
518
+ * @param {string | number[] | Uint8Array | ArrayBuffer} data 待编码数据
519
+ * @returns {string} URL安全的Base64字符串
520
+ */
521
+ const encodeURI = function (data) {
522
+ return encode(data, true);
523
+ };
524
+ /**
525
+ * URL安全Base64解码(专用方法,兼容URL安全字符)
526
+ * @param {string} base64Str URL安全的Base64字符串
527
+ * @returns {string} 解码后的UTF8字符串
528
+ */
529
+ const decodeURI = function (base64Str) {
530
+ return decode(base64Str);
339
531
  };
340
- /* 以下是内部实现需要的es模块化导出方法 */
341
- const utf8Encode = utf8Base64Encode;
342
- const utf8Decode = utf8Base64Decode;
343
532
 
344
533
  exports.decode = decode;
345
- exports.decodeAsBytes = decodeAsBytes;
534
+ exports.decodeURI = decodeURI;
346
535
  exports.encode = encode;
347
- exports.utf8Decode = utf8Decode;
348
- exports.utf8Encode = utf8Encode;
536
+ exports.encodeURI = encodeURI;
537
+ exports.fromHex = fromHex;
538
+ exports.fromUint8Array = fromUint8Array;
539
+ exports.toHex = toHex;
540
+ exports.toUint8Array = toUint8Array;