const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); /** * 生成随机字符串 */ function generateRandomString(length = 32, charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') { let result = ''; for (let i = 0; i < length; i++) { result += charset.charAt(Math.floor(Math.random() * charset.length)); } return result; } /** * 生成UUID */ function generateUUID() { return crypto.randomUUID(); } /** * 生成MD5哈希 */ function generateMD5(data) { return crypto.createHash('md5').update(data).digest('hex'); } /** * 生成SHA256哈希 */ function generateSHA256(data) { return crypto.createHash('sha256').update(data).digest('hex'); } /** * 延迟函数 */ function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * 深度克隆对象 */ function deepClone(obj) { if (obj === null || typeof obj !== 'object') { return obj; } if (obj instanceof Date) { return new Date(obj.getTime()); } if (obj instanceof Array) { return obj.map(item => deepClone(item)); } if (typeof obj === 'object') { const clonedObj = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { clonedObj[key] = deepClone(obj[key]); } } return clonedObj; } } /** * 格式化文件大小 */ function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } /** * 格式化时间差 */ function formatTimeDiff(startTime, endTime = Date.now()) { const diff = endTime - startTime; const seconds = Math.floor(diff / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (days > 0) return `${days}天${hours % 24}小时`; if (hours > 0) return `${hours}小时${minutes % 60}分钟`; if (minutes > 0) return `${minutes}分钟${seconds % 60}秒`; return `${seconds}秒`; } /** * 验证邮箱格式 */ function isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } /** * 验证URL格式 */ function isValidURL(url) { try { new URL(url); return true; } catch { return false; } } /** * 清理字符串(移除HTML标签和特殊字符) */ function sanitizeString(str) { if (typeof str !== 'string') return ''; return str .replace(/<[^>]*>/g, '') // 移除HTML标签 .replace(/[<>'"&]/g, '') // 移除危险字符 .trim(); } /** * 截断字符串 */ function truncateString(str, maxLength, suffix = '...') { if (typeof str !== 'string') return ''; if (str.length <= maxLength) return str; return str.substring(0, maxLength - suffix.length) + suffix; } /** * 检查文件是否存在 */ function fileExists(filePath) { try { return fs.existsSync(filePath); } catch { return false; } } /** * 确保目录存在 */ function ensureDirectoryExists(dirPath) { try { if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } return true; } catch (error) { console.error('创建目录失败:', error); return false; } } /** * 读取JSON文件 */ function readJSONFile(filePath) { try { const data = fs.readFileSync(filePath, 'utf8'); return JSON.parse(data); } catch (error) { console.error('读取JSON文件失败:', error); return null; } } /** * 写入JSON文件 */ function writeJSONFile(filePath, data) { try { const jsonString = JSON.stringify(data, null, 2); fs.writeFileSync(filePath, jsonString, 'utf8'); return true; } catch (error) { console.error('写入JSON文件失败:', error); return false; } } /** * 获取文件扩展名 */ function getFileExtension(filename) { return path.extname(filename).toLowerCase(); } /** * 获取文件名(不含扩展名) */ function getFileNameWithoutExtension(filename) { return path.basename(filename, path.extname(filename)); } /** * 转换为驼峰命名 */ function toCamelCase(str) { return str.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase()); } /** * 转换为kebab命名 */ function toKebabCase(str) { return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); } /** * 防抖函数 */ function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } /** * 节流函数 */ function throttle(func, limit) { let inThrottle; return function executedFunction(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } /** * 重试函数 */ async function retry(fn, maxAttempts = 3, delay = 1000) { let lastError; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await fn(); } catch (error) { lastError = error; if (attempt === maxAttempts) { throw lastError; } console.warn(`尝试 ${attempt} 失败,${delay}ms后重试:`, error.message); await new Promise(resolve => setTimeout(resolve, delay)); } } } /** * 并行执行函数并限制并发数 */ async function parallelLimit(tasks, limit = 5) { const results = []; const executing = []; for (const task of tasks) { const promise = Promise.resolve().then(() => task()).then(result => { executing.splice(executing.indexOf(promise), 1); return result; }); results.push(promise); if (results.length >= limit) { executing.push(promise); if (executing.length >= limit) { await Promise.race(executing); } } } return Promise.all(results); } module.exports = { generateRandomString, generateUUID, generateMD5, generateSHA256, delay, deepClone, formatFileSize, formatTimeDiff, isValidEmail, isValidURL, sanitizeString, truncateString, fileExists, ensureDirectoryExists, readJSONFile, writeJSONFile, getFileExtension, getFileNameWithoutExtension, toCamelCase, toKebabCase, debounce, throttle, retry, parallelLimit };