endecode-lib.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. /**
  2. * 本库提供几个常用方法:
  3. * 1、enDecodeTools.uniEncode(text); 将中文进行Unicode编码并输出
  4. * 2、enDecodeTools.base64Encode(text); 将文字进行base64编码并输出
  5. * 3、enDecodeTools.base64Decode(text); 将经过base64编码的文字进行base64解码并输出
  6. * 4、enDecodeTools.utf8Encode(text); 将文字进行utf-8编码并输出
  7. * 5、enDecodeTools.utf8Decode(text); 将经过utf-8编码的文字进行utf-8解码并输出
  8. */
  9. import Pako from './pako.js';
  10. import Md5Utils from './md5.js';
  11. let EncodeUtils = (() => {
  12. //base64编码字符集
  13. let _base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  14. //base64解码字符集
  15. let _base64DecodeChars = [
  16. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  17. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  18. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
  19. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
  20. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  21. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
  22. -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  23. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1];
  24. /**
  25. * 此方法实现中文向Unicode的转码,与Jre中的"native2ascii"命令一样
  26. * @param {String} text 需要进行转码的字符串
  27. * @return {String} Unicode码
  28. */
  29. let _uniEncode = function (text) {
  30. let res = [];
  31. for (let i = 0; i < text.length; i++) {
  32. res[i] = ("00" + text.charCodeAt(i).toString(16)).slice(-4);
  33. }
  34. return "\\u" + res.join("\\u");
  35. };
  36. /**
  37. * 此方法用于将Unicode码解码为正常字符串
  38. * @param {Object} text
  39. */
  40. let _uniDecode = function (text) {
  41. text = text = text.replace(/(\\)?\\u/gi, "%u").replace('%u0025', '%25');
  42. text = unescape(text.toString().replace(/%2B/g, "+"));
  43. let matches = text.match(/(%u00([0-9A-F]{2}))/gi);
  44. if (matches) {
  45. for (let matchid = 0; matchid < matches.length; matchid++) {
  46. let code = matches[matchid].substring(1, 3);
  47. let x = Number("0x" + code);
  48. if (x >= 128) {
  49. text = text.replace(matches[matchid], code);
  50. }
  51. }
  52. }
  53. text = unescape(text.toString().replace(/%2B/g, "+"));
  54. return text;
  55. };
  56. /**
  57. * 此方法用于将文字进行UTF-8编码
  58. * @param {Object} str 源码
  59. * @return {String} UTF-8码
  60. */
  61. let _utf8Encode = function (str) {
  62. let out, i, len, c;
  63. out = "";
  64. len = str.length;
  65. for (i = 0; i < len; i++) {
  66. c = str.charCodeAt(i);
  67. if ((c >= 0x0001) && (c <= 0x007F)) {
  68. out += str.charAt(i);
  69. } else if (c > 0x07FF) {
  70. out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
  71. out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
  72. out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
  73. } else {
  74. out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
  75. out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
  76. }
  77. }
  78. return out;
  79. };
  80. /**
  81. * 此方法用于将文字进行UTF-8解码
  82. * @param {Object} str
  83. * @return {String} 原文字
  84. */
  85. let _utf8Decode = function (str) {
  86. let out, i, len, c;
  87. let char2, char3;
  88. out = "";
  89. len = str.length;
  90. i = 0;
  91. while (i < len) {
  92. c = str.charCodeAt(i++);
  93. switch (c >> 4) {
  94. case 0:
  95. case 1:
  96. case 2:
  97. case 3:
  98. case 4:
  99. case 5:
  100. case 6:
  101. case 7:
  102. // 0xxxxxxx
  103. out += str.charAt(i - 1);
  104. break;
  105. case 12:
  106. case 13:
  107. // 110x xxxx  10xx xxxx
  108. char2 = str.charCodeAt(i++);
  109. out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
  110. break;
  111. case 14:
  112. // 1110 xxxx 10xx xxxx 10xx xxxx
  113. char2 = str.charCodeAt(i++);
  114. char3 = str.charCodeAt(i++);
  115. out += String.fromCharCode(((c & 0x0F) << 12) |
  116. ((char2 & 0x3F) << 6) |
  117. ((char3 & 0x3F) << 0));
  118. break;
  119. }
  120. }
  121. return out;
  122. };
  123. /**
  124. * 此方法用于将文字进行base64编码
  125. * @param {Object} str 源码
  126. * @return {String} base64码
  127. */
  128. let _base64Encode = function (str) {
  129. let out, i, len;
  130. let c1, c2, c3;
  131. len = str.length;
  132. i = 0;
  133. out = "";
  134. while (i < len) {
  135. c1 = str.charCodeAt(i++) & 0xff;
  136. if (i == len) {
  137. out += _base64EncodeChars.charAt(c1 >> 2);
  138. out += _base64EncodeChars.charAt((c1 & 0x3) << 4);
  139. out += "==";
  140. break;
  141. }
  142. c2 = str.charCodeAt(i++);
  143. if (i == len) {
  144. out += _base64EncodeChars.charAt(c1 >> 2);
  145. out += _base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
  146. out += _base64EncodeChars.charAt((c2 & 0xF) << 2);
  147. out += "=";
  148. break;
  149. }
  150. c3 = str.charCodeAt(i++);
  151. out += _base64EncodeChars.charAt(c1 >> 2);
  152. out += _base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
  153. out += _base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
  154. out += _base64EncodeChars.charAt(c3 & 0x3F);
  155. }
  156. return out;
  157. };
  158. /**
  159. * 此方法用于将文字进行base64解码
  160. * @param {Object} str 源码
  161. * @return {String} 源码
  162. */
  163. let _base64Decode = function (str) {
  164. let c1, c2, c3, c4;
  165. let i, len, out;
  166. len = str.length;
  167. i = 0;
  168. out = "";
  169. while (i < len) {
  170. /* c1 */
  171. do {
  172. c1 = _base64DecodeChars[str.charCodeAt(i++) & 0xff];
  173. }
  174. while (i < len && c1 == -1);
  175. if (c1 == -1)
  176. break;
  177. /* c2 */
  178. do {
  179. c2 = _base64DecodeChars[str.charCodeAt(i++) & 0xff];
  180. }
  181. while (i < len && c2 == -1);
  182. if (c2 == -1)
  183. break;
  184. out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
  185. /* c3 */
  186. do {
  187. c3 = str.charCodeAt(i++) & 0xff;
  188. if (c3 == 61)
  189. return out;
  190. c3 = _base64DecodeChars[c3];
  191. }
  192. while (i < len && c3 == -1);
  193. if (c3 == -1)
  194. break;
  195. out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
  196. /* c4 */
  197. do {
  198. c4 = str.charCodeAt(i++) & 0xff;
  199. if (c4 == 61)
  200. return out;
  201. c4 = _base64DecodeChars[c4];
  202. }
  203. while (i < len && c4 == -1);
  204. if (c4 == -1)
  205. break;
  206. out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
  207. }
  208. return out;
  209. };
  210. /**
  211. * 中文,一般情况下Unicode是UTF-16实现,长度2位,而UTF-8编码是3位
  212. * @param str
  213. * @return {String}
  214. */
  215. let _utf16to8 = function (str) {
  216. return str.replace(/\\x/g, '%');
  217. };
  218. let _utf8to16 = function (str) {
  219. return str.replace(/%/g, '\\x');
  220. };
  221. /**
  222. * md5加密
  223. * @param str
  224. */
  225. let md5 = (str) => {
  226. return Md5Utils.md5(str);
  227. };
  228. /**
  229. * gzip加密
  230. * @param str
  231. * @returns {*}
  232. */
  233. let gzipEncode = str => {
  234. try {
  235. return window.btoa(Pako.gzip(escape(str), {to: "string"}));
  236. } catch (e) {
  237. return 'Error: 当前字符串不能被Gzip加密';
  238. }
  239. };
  240. /**
  241. * gzip解密
  242. * @param str
  243. * @returns {string}
  244. */
  245. let gzipDecode = str => {
  246. try {
  247. let charData = window.atob(str).split('').map(x => x.charCodeAt(0));
  248. let data = Pako.inflate(new Uint8Array(charData));
  249. let result = String.fromCharCode.apply(null, new Uint16Array(data));
  250. try {
  251. return unescape(result);
  252. } catch (ee) {
  253. return result;
  254. }
  255. } catch (e) {
  256. return 'Error: 当前字符串不能被Gzip解密';
  257. }
  258. };
  259. /**
  260. * 字符串与Hex编码互转
  261. * @param input
  262. * @returns {string}
  263. */
  264. let hexTools = (function (input) {
  265. let utf8encode = function (str, isGetBytes) {
  266. let back = [];
  267. let byteSize = 0;
  268. for (let i = 0; i < str.length; i++) {
  269. let code = str.charCodeAt(i);
  270. if (0x00 <= code && code <= 0x7f) {
  271. byteSize += 1;
  272. back.push(code);
  273. } else if (0x80 <= code && code <= 0x7ff) {
  274. byteSize += 2;
  275. back.push((192 | (31 & (code >> 6))));
  276. back.push((128 | (63 & code)))
  277. } else if ((0x800 <= code && code <= 0xd7ff)
  278. || (0xe000 <= code && code <= 0xffff)) {
  279. byteSize += 3;
  280. back.push((224 | (15 & (code >> 12))));
  281. back.push((128 | (63 & (code >> 6))));
  282. back.push((128 | (63 & code)))
  283. }
  284. }
  285. for (let i = 0; i < back.length; i++) {
  286. back[i] &= 0xff;
  287. }
  288. if (isGetBytes) {
  289. return back
  290. }
  291. if (byteSize <= 0xff) {
  292. return [0, byteSize].concat(back);
  293. } else {
  294. return [byteSize >> 8, byteSize & 0xff].concat(back);
  295. }
  296. };
  297. let utf8decode = function (arr) {
  298. if (typeof arr === 'string') {
  299. return arr;
  300. }
  301. let UTF = '', _arr = arr;
  302. for (let i = 0; i < _arr.length; i++) {
  303. let one = _arr[i].toString(2),
  304. v = one.match(/^1+?(?=0)/);
  305. if (v && one.length === 8) {
  306. let bytesLength = v[0].length;
  307. let store = _arr[i].toString(2).slice(7 - bytesLength);
  308. for (let st = 1; st < bytesLength; st++) {
  309. store += _arr[st + i].toString(2).slice(2)
  310. }
  311. UTF += String.fromCharCode(parseInt(store, 2));
  312. i += bytesLength - 1
  313. } else {
  314. UTF += String.fromCharCode(_arr[i])
  315. }
  316. }
  317. return UTF
  318. };
  319. let hexEncode = function (str) {
  320. let charBuf = utf8encode(str, true);
  321. let re = '';
  322. for (let i = 0; i < charBuf.length; i++) {
  323. let x = (charBuf[i] & 0xFF).toString(16);
  324. if (x.length === 1) {
  325. x = '0' + x;
  326. }
  327. re += x;
  328. }
  329. return re;
  330. };
  331. let hexDecode = function (str) {
  332. let buf = [];
  333. for (let i = 0; i < str.length; i += 2) {
  334. buf.push(parseInt(str.substring(i, i + 2), 16));
  335. }
  336. return utf8decode(buf);
  337. };
  338. return {hexEncode, hexDecode};
  339. })();
  340. /**
  341. * html代码转换成js
  342. * @param txt
  343. * @returns {string}
  344. */
  345. let _html2js = function (txt) {
  346. let htmlArr = txt.replace(/\\/g, "\\\\").replace(/\\/g, "\\/").replace(/\'/g, "\\\'").split('\n');
  347. let len = htmlArr.length;
  348. let outArr = [];
  349. outArr.push("let htmlCodes = [\n");
  350. htmlArr.forEach((value, index) => {
  351. if (value !== "") {
  352. if (index === len - 1) {
  353. outArr.push("\'" + value + "\'");
  354. } else {
  355. outArr.push("\'" + value + "\',\n");
  356. }
  357. }
  358. });
  359. outArr.push("\n].join(\"\");");
  360. return outArr.join("");
  361. };
  362. /**
  363. * URL 参数解析
  364. * @param url
  365. * @returns {{url: *, params: Array}}
  366. * @private
  367. */
  368. let _urlParamsDecode = function (url) {
  369. let res = {};
  370. try {
  371. let params = [];
  372. let urlObj = new URL(url);
  373. for (let item of urlObj.searchParams) {
  374. params.push(item);
  375. }
  376. res = {
  377. url: urlObj.href,
  378. params: params,
  379. protocol: urlObj.protocol,
  380. pathname: urlObj.pathname,
  381. hostname: urlObj.hostname
  382. }
  383. } catch (e) {
  384. res.error = '这不是一个合法的URL!无法完成解析!'
  385. }
  386. return res;
  387. };
  388. // sha1加密
  389. let _sha1Encode = function (str) {
  390. function encodeUTF8(s) {
  391. let i, r = [], c, x;
  392. for (i = 0; i < s.length; i++)
  393. if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
  394. else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
  395. else {
  396. if ((x = c ^ 0xD800) >> 10 == 0)
  397. c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
  398. r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
  399. else r.push(0xE0 + (c >> 12 & 0xF));
  400. r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
  401. }
  402. return r;
  403. }
  404. var data = new Uint8Array(encodeUTF8(str))
  405. var i, j, t;
  406. var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2);
  407. s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
  408. for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2);
  409. s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
  410. s[l - 1] = data.length << 3;
  411. var w = [], f = [
  412. function () { return m[1] & m[2] | ~m[1] & m[3]; },
  413. function () { return m[1] ^ m[2] ^ m[3]; },
  414. function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; },
  415. function () { return m[1] ^ m[2] ^ m[3]; }
  416. ], rol = function (n, c) { return n << c | n >>> (32 - c); },
  417. k = [1518500249, 1859775393, -1894007588, -899497514],
  418. m = [1732584193, -271733879, null, null, -1009589776];
  419. m[2] = ~m[0], m[3] = ~m[1];
  420. for (i = 0; i < s.length; i += 16) {
  421. var o = m.slice(0);
  422. for (j = 0; j < 80; j++)
  423. w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
  424. t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
  425. m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
  426. for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0;
  427. };
  428. t = new DataView(new Uint32Array(m).buffer);
  429. for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2);
  430. var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) {
  431. return (e < 16 ? "0" : "") + e.toString(16);
  432. }).join("");
  433. return hex;
  434. };
  435. return {
  436. uniEncode: _uniEncode,
  437. uniDecode: _uniDecode,
  438. base64Encode: _base64Encode,
  439. base64Decode: _base64Decode,
  440. utf8Encode: _utf8Encode,
  441. utf8Decode: _utf8Decode,
  442. utf16to8: _utf16to8,
  443. utf8to16: _utf8to16,
  444. md5: md5,
  445. gzipEncode: gzipEncode,
  446. gzipDecode: gzipDecode,
  447. hexEncode: hexTools.hexEncode,
  448. hexDecode: hexTools.hexDecode,
  449. html2js: _html2js,
  450. urlParamsDecode: _urlParamsDecode,
  451. sha1Encode: _sha1Encode
  452. };
  453. })();
  454. export default EncodeUtils;