Ajouts de la version non sécurisée + Makefile + Générateur de fichiers .db

This commit is contained in:
2024-12-02 20:45:45 +01:00
parent 675eaface8
commit abd096bb21
10 changed files with 943 additions and 0 deletions

13
Unsecured/Makefile Normal file
View File

@@ -0,0 +1,13 @@
# Nom de l'exécutable
TARGET = unsecured_transaction
# Fichier source
SRC = unsecured_transaction.c
# Règle par défaut : compilation et lien
all:
gcc $(SRC) -o $(TARGET)
# Nettoyage des fichiers générés
clean:
rm -f $(TARGET)

31
Unsecured/README.md Normal file
View File

@@ -0,0 +1,31 @@
@TODO : Améliorer le README.MD (le texte y compris)
# 🏦 Simulateur de Transactions Bancaires Concurrentes
Ce programme en C simule des transactions bancaires aléatoires entre comptes dans un environnement multi-processus. Il est conçu pour illustrer les défis de la concurrence sans synchronisation explicite.
## ✨ Fonctionnalités
- 📖 **Lecture et écriture de comptes** : Les comptes sont stockés dans un fichier avec un format fixe (nom et solde).
- 🔄 **Transactions aléatoires** : Effectue des transferts d'argent aléatoires entre comptes.
- 🤹 **Simulation multi-processus** : Plusieurs processus enfants effectuent des transactions simultanément.
- 📊 **Calcul des soldes** : Affiche le solde total avant et après les transactions.
---
## ⚠️ Limitations et Bugs Potentiels
🚨 **Ce programme n'utilise pas de mécanismes de verrouillage pour gérer la concurrence.**
1. **💥 Problème de concurrence** :
- Plusieurs processus peuvent lire et écrire dans le fichier en même temps, entraînant des incohérences dans les soldes (race condition).
- Par exemple, deux processus modifiant simultanément un compte peuvent écraser leurs changements.
2. **📉 Corruption des données** :
- Une interruption (crash ou arrêt forcé) pendant une transaction peut laisser des données partiellement écrites.
3. **❌ Absence de validations robustes** :
- Aucune vérification supplémentaire pour s'assurer que les montants transférés sont cohérents en cas de concurrence.
---

View File

@@ -0,0 +1,165 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/wait.h>
#include <string.h>
#define ACCOUNT_SIZE 16
#define MAX_NAME_LEN 10
#define MAX_BALANCE_LEN 5
#define FILENAME "../Data/accounts.db"
// Fonction pour lire un compte dans le fichier
void read_account(int fd, int index, char *name, int *balance) {
char buffer[ACCOUNT_SIZE];
lseek(fd, index * ACCOUNT_SIZE, SEEK_SET);
read(fd, buffer, ACCOUNT_SIZE);
sscanf(buffer, "%10s %d", name, balance);
}
// Fonction pour écrire un compte dans le fichier
void write_account(int fd, int index, const char *name, int balance) {
char buffer[ACCOUNT_SIZE];
// Créer une chaîne formatée avec une largeur fixe
snprintf(buffer, ACCOUNT_SIZE - 1, "%-10s%4d", name, balance);
// Assurer que le buffer termine par '\n'
buffer[ACCOUNT_SIZE - 1] = '\n';
// Positionner et écrire dans le fichier
lseek(fd, index * ACCOUNT_SIZE, SEEK_SET);
write(fd, buffer, ACCOUNT_SIZE);
}
// Fonction pour effectuer une transaction
void perform_transaction(int fd, int account_count) {
int from_idx = rand() % account_count;
int to_idx = rand() % account_count;
while (from_idx == to_idx) {
to_idx = rand() % account_count;
}
char from_name[MAX_NAME_LEN], to_name[MAX_NAME_LEN];
int from_balance, to_balance;
// Lire les comptes source et destination
read_account(fd, from_idx, from_name, &from_balance);
read_account(fd, to_idx, to_name, &to_balance);
// Calculer un montant aléatoire à transférer (max 20% du solde source)
int max_transfer = from_balance / 5;
if (max_transfer > 0) {
int transfer_amount = rand() % max_transfer;
// Effectuer la transaction
from_balance -= transfer_amount;
to_balance += transfer_amount;
// Écrire les nouveaux soldes dans le fichier
write_account(fd, from_idx, from_name, from_balance);
write_account(fd, to_idx, to_name, to_balance);
printf("Transaction : %s -> %s : %d€\n", from_name, to_name, transfer_amount);
} else {
printf("Transaction annulée : Fonds insufisants %s\n", from_name);
}
}
// Fonction pour un processus de transactions
void process_transactions(int transactions, int account_count) {
int fd = open(FILENAME, O_RDWR);
if (fd < 0) {
perror("Erreur : Impossible d'ouvrir le fichier");
exit(1);
}
for (int i = 0; i < transactions; i++) {
perform_transaction(fd, account_count);
usleep(rand() % 100000); // Temporisation aléatoire
}
close(fd);
}
int calculate_total_balance() {
int fd = open(FILENAME, O_RDONLY);
if (fd < 0) {
perror("Erreur : Impossible d'ouvrir le fichier");
return -1;
}
off_t file_size = lseek(fd, 0, SEEK_END);
int account_count = file_size / ACCOUNT_SIZE;
int total_balance = 0;
char name[MAX_NAME_LEN];
int balance;
for (int i = 0; i < account_count; i++) {
read_account(fd, i, name, &balance);
total_balance += balance;
}
close(fd);
return total_balance;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <number_of_processes> <transactions_per_process>\n", argv[0]);
return 1;
}
int num_processes = atoi(argv[1]);
int transactions_per_process = atoi(argv[2]);
srand(time(NULL));
// Calcul du solde total initial
int initial_balance = calculate_total_balance();
if (initial_balance < 0) {
return 1; // Erreur lors de l'ouverture du fichier
}
printf("Solde total initial : %d€\n", initial_balance);
// Ouvrir le fichier pour déterminer le nombre de comptes
int fd = open(FILENAME, O_RDONLY);
if (fd < 0) {
perror("Erreur : Impossible d'ouvrir le fichier");
return 1;
}
off_t file_size = lseek(fd, 0, SEEK_END);
close(fd);
int account_count = file_size / ACCOUNT_SIZE;
printf("Nombre de comptes : %d\n", account_count);
// Créer les processus enfants
for (int i = 0; i < num_processes; i++) {
if (fork() == 0) {
process_transactions(transactions_per_process, account_count);
exit(0);
}
}
// Attendre les processus enfants
for (int i = 0; i < num_processes; i++) {
wait(NULL);
}
// Calcul du solde total final
int final_balance = calculate_total_balance();
if (final_balance < 0) {
return 1; // Erreur lors de l'ouverture du fichier
}
printf("Solde total final : %d€\n", final_balance);
printf("Tout les processus sont terminés !\n");
return 0;
}