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()}'); } }