PACKET v1.0.0 - Initial release
App móvil Flutter para capturar contenido multimedia, etiquetarlo con hashes y enviarlo a backends configurables. Features: - Captura de fotos, audio, video y archivos - Sistema de etiquetas con bibliotecas externas (HST) - Packs de etiquetas predefinidos - Cola de reintentos (hasta 20 contenedores) - Soporte GPS - Hash SHA-256 auto-generado por contenedor - Persistencia SQLite local - Múltiples destinos configurables Stack: Flutter 3.38.5, flutter_bloc, sqflite, dio 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
36
lib/core/utils/hash_utils.dart
Normal file
36
lib/core/utils/hash_utils.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
||||
class HashUtils {
|
||||
static final _random = Random.secure();
|
||||
|
||||
static String generateHash() {
|
||||
final bytes = List<int>.generate(32, (_) => _random.nextInt(256));
|
||||
return sha256.convert(bytes).toString();
|
||||
}
|
||||
|
||||
static String hashFromBytes(Uint8List bytes) {
|
||||
return sha256.convert(bytes).toString();
|
||||
}
|
||||
|
||||
static String hashFromString(String input) {
|
||||
return sha256.convert(utf8.encode(input)).toString();
|
||||
}
|
||||
|
||||
static bool isValidHash(String hash) {
|
||||
if (hash.length != 64) return false;
|
||||
return RegExp(r'^[a-f0-9]{64}$').hasMatch(hash);
|
||||
}
|
||||
|
||||
static List<String> extractHashes(String text) {
|
||||
final regex = RegExp(r'[a-f0-9]{64}');
|
||||
return regex.allMatches(text).map((m) => m.group(0)!).toList();
|
||||
}
|
||||
|
||||
static String truncateHash(String hash, {int length = 8}) {
|
||||
if (hash.length <= length) return hash;
|
||||
return '${hash.substring(0, length)}...';
|
||||
}
|
||||
}
|
||||
20
lib/core/utils/retry_utils.dart
Normal file
20
lib/core/utils/retry_utils.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import '../constants/app_constants.dart';
|
||||
|
||||
class RetryUtils {
|
||||
static DateTime calculateNextRetry(int intentoActual) {
|
||||
final delay = RetryDelays.getDelay(intentoActual);
|
||||
return DateTime.now().add(delay);
|
||||
}
|
||||
|
||||
static bool shouldRetry(int intentos) {
|
||||
return intentos < AppConstants.maxReintentos;
|
||||
}
|
||||
|
||||
static String formatTimeRemaining(DateTime nextRetry) {
|
||||
final diff = nextRetry.difference(DateTime.now());
|
||||
if (diff.isNegative) return 'Ahora';
|
||||
if (diff.inHours > 0) return '${diff.inHours}h ${diff.inMinutes % 60}m';
|
||||
if (diff.inMinutes > 0) return '${diff.inMinutes}m';
|
||||
return '${diff.inSeconds}s';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user