Corrigé NSI Antilles 2026 – Jour 1
Bac général 2026 • NSI • Antilles-Guyane • Jour 1

Corrigé NSI Antilles 2026 jour 1

Cette correction traite intégralement les trois exercices : modèle relationnel et SQL, recherche de plus longue sous-séquence commune, puis routage, sécurisation des communications et programmation orientée objet.

SQLBases de donnéesRécursivitéProgrammation dynamiqueRIP et OSPFCryptographiePython objet
VOIR LE CORRIGÉFICHES NSI – PROCHAINEMENTLEXIQUE NSI – PROCHAINEMENT

En résumé : ce qu’il fallait maîtriser

DonnéesClés primaires et étrangères, contraintes d’intégrité, jointures, agrégations, mises à jour et sécurisation d’un SGBD.
AlgorithmesRecherche exhaustive exponentielle, récursivité, sous-problèmes répétés, mémoïsation et programmation dynamique.
Machines et réseauxDNS, RIP, OSPF, tolérance aux pannes, HTTPS, chiffrement hybride, signature et classe Python.

Analyse du sujet : les attentes du programme

Le sujet croise les quatre concepts fondamentaux de la NSI : les données sont organisées dans une base relationnelle ; les algorithmes produisent une LCS et illustrent la différence entre recherche exhaustive et programmation dynamique ; les langages SQL et Python traduisent les traitements ; les machines communiquent sur un réseau grâce à des protocoles de routage et de sécurité.

La difficulté n’est pas seulement syntaxique. Le correcteur attend que l’élève justifie les contraintes relationnelles, analyse le coût d’un algorithme, explique la redondance des appels récursifs et distingue clairement chiffrement symétrique, asymétrique et signature.

Règle de rédaction : pour une question de code, donner le programme puis expliquer brièvement pourquoi il satisfait la spécification. Pour une question de réseau ou de sécurité, nommer le mécanisme et décrire précisément les étapes.

Exercice 1 – Bases de données relationnelles et SQL (6 points)

1. Deux avantages d’un SGBD sur un tableur

Un SGBD offre notamment :

  • des contraintes d’intégrité garantissant l’unicité des clés, les types des attributs et la cohérence des références ;
  • une gestion efficace des accès concurrents, des droits d’accès et de la sécurité ;
  • des requêtes performantes sur un grand volume de données ;
  • une réduction des redondances grâce à plusieurs relations liées entre elles.
Deux réponses suffisaient, par exemple intégrité des données et gestion des accès simultanés.

2. Deux pizzas de même numéro mais de couleurs différentes ?

Non. L’attribut num est la clé primaire de la relation pizza. Une clé primaire identifie de manière unique chaque ligne : deux pizzas ne peuvent donc pas avoir le même numéro, quels que soient leur prix ou leur couleur.

3. Exemple de clé étrangère

commande.id_client est une clé étrangère qui référence client.id. On pouvait aussi citer commande.num_pizza, qui référence pizza.num.

4. Résultat de la requête sur les pizzas Bianca

SELECT prix
FROM pizza
WHERE couleur = 'Bianca';

Les pizzas n°2 et n°4 sont blanches. La requête renvoie donc deux lignes :

11.5
15.5

5. Couleurs des pizzas coûtant plus de 15 €

SELECT couleur
FROM pizza
WHERE prix > 15;

Avec l’extrait fourni, la réponse est Bianca. L’ajout de DISTINCT serait acceptable si l’on souhaitait éviter d’éventuels doublons.

6. Prénoms des clients livrés mais n’ayant pas payé

SELECT DISTINCT client.prenom
FROM client
JOIN commande ON client.id = commande.id_client
WHERE commande.livraison = 1
  AND commande.paiement = 0;

Dans l’extrait, la commande 42364 correspond à Raffaele.

7. Prix moyen des pizzas commandées par Esposito

SELECT AVG(pizza.prix)
FROM client
JOIN commande ON client.id = commande.id_client
JOIN pizza ON commande.num_pizza = pizza.num
WHERE client.nom = 'Esposito';

Dans l’extrait, Giulia Esposito a commandé les pizzas 2, 3 et 1 : la moyenne vaut (11,5 + 12,5 + 11,5) / 3, soit environ 11,83 €.

8. Mettre à jour la livraison de la commande 42365

UPDATE commande
SET livraison = 1
WHERE code = 42365;

9. Ajouter Emanuele Girasole puis sa commande

Le client doit être inséré avant la commande, car la clé étrangère id_client doit référencer un client existant.

INSERT INTO client (id, nom, prenom)
VALUES (107, 'Girasole', 'Emanuele');

INSERT INTO commande
    (code, id_client, num_pizza, date, livraison, paiement)
VALUES
    (42366, 107, 2, '2025-01-03', 0, 0);

Les valeurs 0 indiquent que la commande vient d’être enregistrée et n’est encore ni livrée ni payée. Si le système commercial imposait un paiement immédiat, seule la dernière valeur devrait être adaptée.

10. Problème posé par la suppression de la pizza n°1

Des lignes de commande référencent déjà la pizza n°1. La suppression viole donc la contrainte d’intégrité référentielle. Selon la configuration du SGBD, la requête sera refusée ou une suppression en cascade effacerait aussi l’historique des commandes, ce qui serait indésirable.

Solution métier préférable : ajouter un attribut indiquant qu’une pizza n’est plus commercialisée plutôt que supprimer son enregistrement historique.

11. Relations ingredient et composition

ingredient(
    id_ingredient : entier,
    nom : texte
)

composition(
    num_pizza : entier,
    id_ingredient : entier
)

La clé primaire de ingredient est id_ingredient. La clé primaire de composition est le couple (num_pizza, id_ingredient). Ses deux attributs sont aussi des clés étrangères : num_pizza référence pizza.num et id_ingredient référence ingredient.id_ingredient.

12. Mise en ligne de la base : risques et précautions

Une base accessible depuis Internet est exposée aux accès non autorisés, au vol ou à la modification des données personnelles, aux injections SQL, à l’usurpation d’identité et aux attaques par déni de service.

Il faut notamment utiliser HTTPS, authentifier les utilisateurs, limiter les droits selon les rôles, employer des requêtes paramétrées, filtrer les entrées, protéger les mots de passe par hachage salé, configurer pare-feu et mises à jour, journaliser les accès et effectuer des sauvegardes. L’accès direct au SGBD ne doit pas être ouvert au public : les requêtes passent par une application serveur sécurisée.

Erreur fréquente : confondre clé primaire et clé étrangère. La première identifie une ligne de sa propre table ; la seconde référence la clé d’une autre relation.

Exercice 2 – LCS, récursivité et programmation dynamique (6 points)

Partie A – Recherche exhaustive

1. Évolution des paramètres

Appellisteaccumulateur
Initial[9, 3, 7][[]]
1er sous-appel[9, 3][[], [7]]
2e sous-appel[9][[], [7], [3], [3, 7]]
Dernier sous-appel[][[], [7], [3], [3, 7], [9], [9, 7], [9, 3], [9, 3, 7]]

À chaque étape, le nombre de sous-listes double : on conserve les anciennes et on ajoute celles qui contiennent l’élément extrait.

2. Compléter sous_listes

def sous_listes(liste: list, accumulateur=[[]]):
    if len(liste) == 0:
        return accumulateur
    element = liste.pop()
    tmp = []
    for sous_liste in accumulateur:
        tmp.append([element] + sous_liste)
    return sous_listes(liste, accumulateur + tmp)

L’expression [element] + sous_liste place bien l’élément en tête. Attention : pop() modifie la liste passée en argument.

3. Pourquoi la force brute est-elle lente ?

Une liste de longueur n possède 2n sous-listes extraites. La fonction les construit toutes, puis teste chacune dans la seconde liste. Le temps d’exécution croît donc au moins de façon exponentielle avec n. Doubler légèrement la taille peut multiplier très fortement le nombre de cas à examiner.

Partie B – Relation de récurrence et approche top-down

4. Résultat de l’appel avec un élément de chaque liste

lcs([9, 3, 7, 5, 8], 1,
    [9, 7, 8, 3, 7, 3], 1)

Les deux préfixes sont [9] et [9]. La fonction renvoie donc [9].

5. Derniers éléments identiques

Si L_1[m-1] == L_2[n-1], on ajoute cet élément commun à une LCS des préfixes privés de leur dernier élément :

lcs(L_1, m-1, L_2, n-1) + [L_1[m-1]]

6. Pourquoi aux est-elle récursive ?

Une fonction est récursive lorsqu’elle s’appelle elle-même. Ici, aux contient des appels à aux(…) aux lignes 6, 7 et 8, avec des indices plus petits. Les cas de base de la ligne 3 arrêtent la récursion quand l’un des préfixes est vide.

7. Risque avec de très grandes listes

Lorsque les derniers éléments diffèrent, deux appels récursifs sont lancés. De nombreux couples d’indices sont recalculés plusieurs fois : l’arbre d’appels peut devenir exponentiel. Le programme risque donc d’être très lent, de consommer beaucoup de mémoire et d’atteindre la profondeur maximale de récursion de Python.

8. Éviter les calculs répétés

On peut utiliser la mémoïsation : mémoriser dans un dictionnaire le résultat associé à chaque couple (index_x, index_y). Chaque sous-problème n’est alors calculé qu’une fois. Une autre solution est une programmation dynamique ascendante remplissant un tableau de taille approximative m×n.

def lcs_memo(liste_x, liste_y):
    memo = {}

    def aux(i, j):
        if i < 0 or j < 0:
            return []
        if (i, j) in memo:
            return memo[(i, j)]
        if liste_x[i] == liste_y[j]:
            resultat = aux(i - 1, j - 1) + [liste_x[i]]
        else:
            r1 = aux(i, j - 1)
            r2 = aux(i - 1, j)
            resultat = r1 if len(r1) >= len(r2) else r2
        memo[(i, j)] = resultat
        return resultat

    return aux(len(liste_x) - 1, len(liste_y) - 1)
Complexité : la mémoïsation ramène le nombre de sous-problèmes à environ m×n, même si le coût exact dépend aussi de la copie des listes résultats.

Exercice 3 – Routage, cryptographie et programmation objet (8 points)

Partie A – Réseaux et sécurisation

1. Chemin RIP de Bob vers le serveur DNS

RIP minimise le nombre de routeurs traversés. Le chemin le plus court en nombre de sauts est :

R1 → R2 → R3 → R8

Les liaisons entre Bob et R1 puis entre R8 et le serveur DNS ne sont pas des routeurs supplémentaires.

2. Chemin OSPF de Bob vers Alice

OSPF minimise la somme des coûts. Le chemin optimal est :

R1 → R2 → R3 → R7 → R6 → R4 → R5

Il utilise les liaisons peu coûteuses entre R3, R7, R6 et R4, même s’il traverse davantage de routeurs que le chemin direct par R2 et R4.

3. Coût du chemin OSPF

R1–R2 : 1
R2–R3 : 1
R3–R7 : 0,1
R7–R6 : 0,1
R6–R4 : 0,01
R4–R5 : 1

Total = 3,21

4. Panne du routeur R3

Les routeurs détectent que les routes passant par R3 ne sont plus disponibles, mettent à jour leurs informations de routage puis choisissent un chemin de remplacement. Pour joindre Alice, Bob peut passer par R1 → R2 → R4 → R5. La communication est momentanément perturbée pendant la convergence, mais le réseau reste fonctionnel grâce aux chemins redondants.

5. Protocole chiffrant les échanges web

Le protocole attendu est HTTPS, c’est-à-dire HTTP protégé par TLS.

6. Rôle de la clé symétrique

La même clé secrète sert à chiffrer les données avant envoi et à les déchiffrer à la réception. Le chiffrement symétrique est rapide et convient au volume important des échanges après l’établissement de la connexion.

7. Transmettre la clé symétrique grâce au chiffrement asymétrique

  1. Alice conserve sa clé privée et transmet sa clé publique à Bob.
  2. Bob chiffre la clé symétrique avec la clé publique d’Alice.
  3. Bob envoie le résultat à Alice.
  4. Seule la clé privée d’Alice permet de déchiffrer le message et de retrouver la clé symétrique.

Un tiers interceptant le message chiffré ne possède pas la clé privée nécessaire.

8. Confidentialité et authenticité avec la signature

L’ensemble contenant la clé symétrique et la signature est chiffré avec la clé publique d’Alice. Alice est donc la seule à pouvoir l’ouvrir grâce à sa clé privée : cela assure la confidentialité.

Alice déchiffre ensuite la signature avec la clé publique de Bob, recalcule le condensé de la clé symétrique reçue et compare les deux condensés. S’ils sont identiques, les données n’ont pas été modifiées et la signature a été produite avec la clé privée associée à la clé publique de Bob. Cela assure l’intégrité et l’authenticité, sous réserve que la clé publique soit réellement celle de Bob.

Partie B – Fonctions du module outils

9. Fonction somme

def somme(tab):
    total = 0
    for valeur in tab:
        total += valeur
    return total

10. Fonction permuter

def permuter(tab, i, j):
    tab[i], tab[j] = tab[j], tab[i]

La fonction modifie directement la liste passée en paramètre et ne doit pas nécessairement renvoyer de valeur.

11. Fonction inverser

def inverser(tab):
    for i in range(len(tab) // 2):
        permuter(tab, i, len(tab) - 1 - i)

Chaque élément de la première moitié est échangé avec son symétrique dans la seconde moitié.

12. Fonction generer_sac

from random import randint

def generer_sac():
    '''
    renvoie un sac (8 entiers)
    : return (list) un sac
    '''
    sac = [randint(1, 5)]
    for i in range(7):
        s = somme(sac)
        nouvel_entier = randint(s + 1, 2 * s)
        sac.append(nouvel_entier)
    inverser(sac)
    return sac

Avant inversion, chaque nouvel entier est strictement supérieur à la somme des précédents. Après inversion, les valeurs sont présentées de la plus grande vers la plus petite, ce qui rend possible le déchiffrement glouton.

Partie C – Classe Cle_symetrique

13. Constructeur de la classe

import outils

class Cle_symetrique:
    def __init__(self):
        self.sac = outils.generer_sac()

14. Méthode chiffrer

def chiffrer(self, octet):
    '''
    renvoie le chiffrement de octet
    : paramètre octet (list) un tableau de huit 0 ou 1
    : return (int)
    '''
    tab_produits = []
    for i in range(8):
        produit = octet[i] * self.sac[i]
        tab_produits.append(produit)
    s = outils.somme(tab_produits)
    return s

15. Déchiffrement de 688

Valeur du sacReste avant décisionBitNouveau reste
5686881120
2051200120
71120149
3249117
101717
6711
2101
1110
Octet retrouvé : [1, 0, 1, 1, 1, 1, 0, 1].

16. Méthode dechiffrer

def dechiffrer(self, entier):
    octet = []
    for valeur in self.sac:
        if entier >= valeur:
            octet.append(1)
            entier -= valeur
        else:
            octet.append(0)
    return octet

L’algorithme parcourt les valeurs du sac de la plus grande à la plus petite. La propriété de super-croissance de la suite initiale garantit qu’un choix glouton permet de retrouver sans ambiguïté les bits.

Précision importante : ce « sac » illustre un principe de chiffrement à des fins pédagogiques. Il ne constitue pas, sous cette forme simplifiée, un système adapté à la protection réelle de données sensibles.

Méthode pour réussir ce sujet de NSI

SQLRepérer d’abord les tables nécessaires et les colonnes qui permettent les jointures.
Code à trousRevenir à la spécification en français et suivre l’état des variables sur un petit exemple.
RécursivitéIdentifier les cas de base, la diminution du problème et les éventuels calculs répétés.
RoutageRIP minimise les sauts ; OSPF additionne les coûts. Ne pas mélanger les deux critères.
CryptographieDistinguer confidentialité, intégrité, authentification et rôle de chaque clé.
Programmation objetUn attribut propre à l’instance s’écrit avec self.
Gestion indicative des 3 h 30 : environ 60 minutes pour l’exercice 1, 65 minutes pour l’exercice 2, 75 minutes pour l’exercice 3, puis 10 minutes de relecture.

Compléter prochainement ses révisions de NSI

Les futures fiches et le futur lexique pourront reprendre les notions essentielles de cette épreuve : modèle relationnel, contraintes d’intégrité, jointure SQL, récursivité, coût exponentiel, mémoïsation, DNS, RIP, OSPF, HTTPS, clés symétriques et asymétriques, signature, modularité et programmation objet.

FICHES NSI – BIENTÔT DISPONIBLESLEXIQUE NSI – EN PRÉPARATIONTOUS LES SUJETS NSIACCUEIL

Télécharger le sujet officiel de NSI

Refaites les trois exercices sans consulter la correction, puis testez les programmes Python proposés sur plusieurs exemples.

DocumentAccès
NSI 2026 Antilles-Guyane – Jour 1
Code : 26-NSIJ1AG1
SUJET OFFICIEL PDF
Corrigé completCORRIGÉ DANS LA PAGE

FAQ

La totalité du sujet NSI est-elle corrigée ?

Oui. Les douze questions de bases de données, les huit questions sur la LCS et les seize questions de réseaux, cryptographie et Python sont traitées.

Pourquoi la force brute sur les sous-listes est-elle exponentielle ?

Une liste de longueur n possède 2ⁿ sous-listes extraites. Les générer et les tester toutes devient rapidement impraticable.

Quelle différence entre récursivité et programmation dynamique ?

La récursivité décrit une solution en termes de sous-problèmes. La programmation dynamique évite de recalculer plusieurs fois les mêmes sous-problèmes, par mémoïsation ou tableau.

Quel est le chemin OSPF vers Alice ?

R1 → R2 → R3 → R7 → R6 → R4 → R5, pour un coût total de 3,21.

Pourquoi utiliser un chiffrement hybride dans HTTPS ?

Le chiffrement asymétrique permet d’échanger une clé secrète sans l’avoir partagée auparavant ; le chiffrement symétrique, plus rapide, protège ensuite les données de la session.

Les fiches et le lexique NSI sont-ils déjà disponibles ?

Non. Ils sont annoncés prochainement et aucun faux lien n’a été créé.