import 'dart:convert'; import 'dart:typed_data'; import 'package:convert/convert.dart' show hex; /// Uint8List <--> Base64 String bytesToBase64(Uint8List data, {bool urlSafe = false}) { try { if (data.isEmpty) { throw ArgumentError('Input data cannot be empty'); } final base64Str = base64Encode(data); if (urlSafe) { return base64Str .replaceAll('+', '-') .replaceAll('/', '_') .replaceAll('=', ''); } return base64Str; } on ArgumentError { rethrow; } catch (e) { throw Exception('Failed to encode Uint8List to Base64: ${e.toString()}'); } } Uint8List base64ToBytes(String base64Str, {bool? urlSafe}) { try { if (base64Str.isEmpty) { throw ArgumentError('Base64 string cannot be empty'); } // 如果未指定 urlSafe,自动检测格式 final isUrlSafe = urlSafe ?? (base64Str.contains('-') || base64Str.contains('_')); String normalizedStr = base64Str; if (isUrlSafe) { // 添加必要的填充字符 final padding = '=' * ((4 - base64Str.length % 4) % 4); normalizedStr = base64Str .replaceAll('-', '+') .replaceAll('_', '/') + padding; } // 验证 Base64 字符串格式 if (!RegExp(r'^[a-zA-Z0-9+/]*={0,2}$').hasMatch(normalizedStr)) { throw FormatException('Invalid Base64 string format'); } return base64Decode(normalizedStr); } on ArgumentError { rethrow; } on FormatException { rethrow; } catch (e) { throw Exception('Failed to decode Base64 to Uint8List: ${e.toString()}'); } } /// 将十六进制字符串直接转换为 Base64 /// /// [hexStr] 十六进制字符串 /// [urlSafe] 是否生成URL安全的Base64 /// /// 返回 Base64 字符串或抛出异常 String hexToBase64(String hexStr, {bool urlSafe = false}) { try { if (hexStr.isEmpty) { throw ArgumentError('Hex string cannot be empty'); } final normalizedHex = hexStr.startsWith('0x') ? hexStr.substring(2) : hexStr; if (!RegExp(r'^[0-9a-fA-F]+$').hasMatch(normalizedHex)) { throw FormatException('Invalid hex string format'); } final bytes = hex.decode(normalizedHex.padLeft( normalizedHex.length + normalizedHex.length % 2, '0' )); final base64 = base64Encode(bytes); return urlSafe ? base64.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '') : base64; } on ArgumentError { rethrow; } on FormatException { rethrow; } catch (e) { throw Exception('Failed to convert hex to Base64: ${e.toString()}'); } } /// 将 Base64 字符串转换为十六进制字符串 /// /// [base64Str] 输入的 Base64 字符串 /// [urlSafe] 输入是否是 URL 安全的 Base64 编码 /// [withPrefix] 是否添加 "0x" 前缀 /// /// 返回十六进制字符串或抛出异常 String base64ToHex(String base64Str, { bool urlSafe = false, bool withPrefix = false, }) { try { if (base64Str.isEmpty) { throw ArgumentError('Base64 string cannot be empty'); } String normalizedStr = base64Str; // 处理 URL 安全的 Base64 if (urlSafe) { // 添加必要的填充字符 final padding = '=' * ((4 - base64Str.length % 4) % 4); normalizedStr = base64Str .replaceAll('-', '+') .replaceAll('_', '/') + padding; } // 验证 Base64 字符串格式 if (!RegExp(r'^[a-zA-Z0-9+/]*={0,2}$').hasMatch(normalizedStr)) { throw FormatException('Invalid Base64 string format'); } // 解码为字节数组 final bytes = base64Decode(normalizedStr); // 转换为十六进制 final hexString = bytes.map((byte) { return byte.toRadixString(16).padLeft(2, '0'); }).join(''); return withPrefix ? '0x$hexString' : hexString; } on ArgumentError { rethrow; } on FormatException { rethrow; } catch (e) { throw Exception('Failed to convert Base64 to hex: ${e.toString()}'); } } /// 将普通字符串转为 Base64,防止携带数据传输出现特殊字符 /// /// [str] 要编码的字符串 /// [urlSafe] 是否生成 URL 安全的 Base64(使用 - 和 _ 替代 + 和 /) /// /// 返回 Base64 字符串或抛出异常 String stringToBase64(String str, {bool urlSafe = false}) { try { if (str.isEmpty) { throw ArgumentError('Input string cannot be empty'); } final bytes = utf8.encode(str); final base64Str = base64Encode(bytes); if (urlSafe) { return base64Str .replaceAll('+', '-') .replaceAll('/', '_') .replaceAll('=', ''); } return base64Str; } on ArgumentError { rethrow; } catch (e) { throw Exception('Failed to encode string to Base64: ${e.toString()}'); } } /// 将 Base64 字符串解码为普通字符串 /// /// [base64Str] 输入的 Base64 字符串 /// [urlSafe] 输入是否是 URL 安全的 Base64 编码(如果为 null 则自动检测) /// /// 返回解码后的字符串或抛出异常 String base64ToString(String base64Str, {bool? urlSafe}) { try { if (base64Str.isEmpty) { throw ArgumentError('Base64 string cannot be empty'); } // 如果未指定 urlSafe,自动检测格式 final isUrlSafe = urlSafe ?? (base64Str.contains('-') || base64Str.contains('_')); String normalizedStr = base64Str; if (isUrlSafe) { // 添加必要的填充字符 final padding = '=' * ((4 - base64Str.length % 4) % 4); normalizedStr = base64Str .replaceAll('-', '+') .replaceAll('_', '/') + padding; } // 验证 Base64 字符串格式 if (!RegExp(r'^[a-zA-Z0-9+/]*={0,2}$').hasMatch(normalizedStr)) { throw FormatException('Invalid Base64 string format'); } // 解码为字节数组 final bytes = base64Decode(normalizedStr); // 转换为 UTF-8 字符串 return utf8.decode(bytes); } on ArgumentError { rethrow; } on FormatException { rethrow; } catch (e) { throw Exception('Failed to decode Base64 to string: ${e.toString()}'); } }