| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- /**
- * 条码/二维码内容编码工具(Base64Url)
- *
- * 设计:
- * - 生成端用 Base64Url 对原文编码,并加 `~` 前缀标识;
- * - 扫码端识别前缀后 Base64Url 解码还原原文;
- * - 无前缀的历史/明文码直接透传,保证向后兼容;
- * - 仅防止肉眼直接读取,不是真正的加密。
- */
- const ENCODE_PREFIX = '~';
- function toBase64Url(str) {
- const b64 = btoa(unescape(encodeURIComponent(str)));
- return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
- }
- function fromBase64Url(str) {
- let b64 = str.replace(/-/g, '+').replace(/_/g, '/');
- while (b64.length % 4) b64 += '=';
- return decodeURIComponent(escape(atob(b64)));
- }
- /**
- * 编码原文:输出 `~` + Base64Url(原文)。
- * @param {string} plain
- * @returns {string}
- */
- export function encryptCode(plain) {
- if (plain == null || plain === '') return '';
- try {
- return ENCODE_PREFIX + toBase64Url(String(plain));
- } catch (e) {
- console.error('encryptCode failed:', e);
- return String(plain);
- }
- }
- /**
- * 解码扫码内容:
- * - 以 `~` 开头:Base64Url 解码还原原文;失败时回退原值;
- * - 不以 `~` 开头:视为明文,直接返回(兼容历史码)。
- * @param {string} code
- * @returns {string}
- */
- export function decryptCode(code) {
- if (code == null || code === '') return '';
- const str = String(code).trim();
- if (!str.startsWith(ENCODE_PREFIX)) return str;
- try {
- return fromBase64Url(str.slice(ENCODE_PREFIX.length));
- } catch (e) {
- console.error('decryptCode failed:', e, code);
- return str;
- }
- }
- export default { encryptCode, decryptCode };
|