Files
XiangYue/js/utils.js
风之暇想 216d5e856f v1.3.0.0
2025-08-01 20:32:40 +08:00

8 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const DEFAULT_PASSWORD='a184f7b849ffffed24d266a30298c72ef2f5ad040db73bf37151fac767630728';const STORAGE_KEYS={THEME_MODE:'theme_mode',OUTPUT_MODE:'output_mode'};const ZERO_WIDTH_REGEX=/[\u200B-\u200F\uFEFF\u202A-\u202E\u2060-\u206F]/u;const BASE64_CHARS_REGEX=/[^A-Za-z0-9+/=]/g;const BASE64_FORMAT_REGEX=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;const EMOJI_REGEX=/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F1E0}-\u{1F1FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/u;const CHINESE_REGEX=/[\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF]/u;const PASSWORD_CHARSET="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+~`|}{[]:;?><,./-='\"\\";const textEncoder=new TextEncoder();(function applyThemeEarly(){const savedThemeMode=localStorage.getItem(STORAGE_KEYS.THEME_MODE);const isDarkMode=savedThemeMode?savedThemeMode==='dark':window.matchMedia('(prefers-color-scheme: dark)').matches;if(isDarkMode){document.documentElement.classList.add('dark');}})();async function handleStream(stream,writerData){const writer=stream.writable.getWriter();await writer.write(writerData);await writer.close();const reader=stream.readable.getReader();const chunks=[];while(true){const{done,value}=await reader.read();if(done)break;chunks.push(value);}
return new Blob(chunks).arrayBuffer();}
const toUint8Array=data=>data instanceof Uint8Array?data:new Uint8Array(typeof data==='string'?textEncoder.encode(data):data);const utils={arrayBufferToBase64:buffer=>sodium.to_base64(new Uint8Array(buffer),sodium.base64_variants.ORIGINAL),base64ToArrayBuffer:base64=>sodium.from_base64(base64,sodium.base64_variants.ORIGINAL).buffer,stringToArrayBuffer:str=>sodium.from_string(str).buffer,arrayBufferToString:buffer=>sodium.to_string(new Uint8Array(buffer)),generateRandomBytes:length=>sodium.randombytes_buf(length),compressData(data){if(typeof pako==='undefined'){throw new Error('压缩失败pako库未加载');}
return pako.deflateRaw(toUint8Array(data),{level:9});},decompressData(data){if(typeof pako==='undefined'){throw new Error('解压失败pako库未加载');}
const uint8Data=toUint8Array(data);try{return pako.inflateRaw(uint8Data);}catch{return pako.inflate(uint8Data);}},generatePassword(length){return Array.from({length},()=>PASSWORD_CHARSET[sodium.randombytes_uniform(PASSWORD_CHARSET.length)]).join('');},copyToClipboard(text){navigator.clipboard.writeText(text).catch(err=>{console.error('复制失败:',err);showNotification('复制到剪贴板失败,请手动复制。',false);});},detectCiphertextType(ciphertext){const limitedText=ciphertext.slice(0,1000);if(ZERO_WIDTH_REGEX.test(limitedText)){return'zero-width';}
const base64Chars=limitedText.replace(BASE64_CHARS_REGEX,'');const base64Ratio=base64Chars.length/limitedText.length;if(base64Ratio>0.8&&BASE64_FORMAT_REGEX.test(base64Chars)){return'base64';}
if(EMOJI_REGEX.test(limitedText)){return'emoji';}
if(CHINESE_REGEX.test(limitedText)){return'chinese';}},saveThemeMode(mode){if(mode==='light'||mode==='dark'){localStorage.setItem(STORAGE_KEYS.THEME_MODE,mode);}},getSavedThemeMode(){return localStorage.getItem(STORAGE_KEYS.THEME_MODE);},saveOutputMode(mode){const validModes=['chinese','base64','emoji','zero-width'];if(validModes.includes(mode)){localStorage.setItem(STORAGE_KEYS.OUTPUT_MODE,mode);}},getSavedOutputMode(){return localStorage.getItem(STORAGE_KEYS.OUTPUT_MODE)||'chinese';}};