Paillasse/portail/public/js/contenus-3.js

93 lines
18 KiB
JavaScript
Raw Permalink Normal View History

// Cours complets · lot 3 : Python, Web, cryptographie
window.CONTENUS_PRO = (window.CONTENUS_PRO || []).concat([
{ id: 'python', match: /Python|programmation|boucle|variable|algorithm/i,
titre: 'Python : variables, conditions, boucles et fonctions', duree: '6 h (CM 2 h · TD 2 h · TP 2 h)', niveau: 'SNT · NSI Première · BTS SIO SLAM · BUT S1',
prerequis: ['Aucun'],
competences: ['NSI 1re · Langages et programmation', 'BTS SIO SLAM · Bloc 2 · Développer une solution applicative', 'BUT Info · Compétence « Réaliser »'],
intro: 'Python est le langage d’enseignement du lycée à l’université, mais aussi celui des administrateurs, des data engineers et de l’IA. Sa syntaxe courte permet de se concentrer sur l’essentiel : décomposer un problème en instructions.',
cm: [
{ t: 'Variables et types', d: '20 min', html: 'Une variable associe un nom à une valeur. Le type est déduit de la valeur.', table: [['Type', 'Exemple', 'Usage'], ['int', '17', 'entiers'], ['float', '3.5', 'nombres à virgule'], ['str', '"Léa"', 'texte'], ['bool', 'True', 'vrai / faux'], ['list', '[12, 15, 9]', 'suite modifiable'], ['dict', '{"nom": "Léa"}', 'associations clé → valeur']], exemple: 'age = 17\nnom = "Léa"\nprint(f"{nom} a {age} ans") # Léa a 17 ans\nprint(type(age)) # <class \'int\'>' },
{ t: 'Opérateurs et entrées', d: '15 min', html: '+ − * / (division réelle), // (division entière), % (reste), ** (puissance). <code>input()</code> lit une saisie, toujours sous forme de texte : on la convertit avec <code>int()</code> ou <code>float()</code>.', attention: 'input() renvoie une chaîne : "3" + "4" donne "34", pas 7.' },
{ t: 'Conditions', d: '20 min', html: 'Le bloc exécuté dépend d’une condition. Python délimite les blocs par l’<b>indentation</b> (4 espaces).', exemple: 'note = float(input("Note : "))\nif note >= 16:\n print("Très bien")\nelif note >= 10:\n print("Admis")\nelse:\n print("À retravailler")' },
{ t: 'Boucle for', d: '20 min', html: '<code>for</code> parcourt une séquence. <code>range(n)</code> produit 0, 1, …, n − 1 ; <code>range(a, b, pas)</code> va de a à b − 1.', exemple: 'notes = [12, 15, 9, 18]\ntotal = 0\nfor n in notes:\n total += n\nprint(total / len(notes)) # 13.5' },
{ t: 'Boucle while', d: '15 min', html: '<code>while</code> répète tant que la condition est vraie. On l’utilise quand on ne connaît pas le nombre de tours à l’avance.', exemple: 'essais = 0\nmdp = ""\nwhile mdp != "paillasse" and essais < 3:\n mdp = input("Mot de passe : ")\n essais += 1', attention: 'Si la condition ne devient jamais fausse, la boucle est infinie. Ctrl+C l’interrompt.' },
{ t: 'Fonctions', d: '20 min', html: 'Une fonction regroupe des instructions réutilisables. Elle reçoit des <b>paramètres</b> et renvoie un résultat avec <code>return</code>. On la documente avec une docstring et on la teste avec <code>assert</code>.', exemple: 'def moyenne(valeurs):\n """Renvoie la moyenne d\'une liste non vide."""\n return sum(valeurs) / len(valeurs)\n\nassert moyenne([10, 20]) == 15' },
{ t: 'Listes et dictionnaires', d: '10 min', html: 'Une liste s’indexe à partir de 0 : <code>notes[0]</code>, <code>notes[-1]</code> (dernier), <code>notes.append(14)</code>. Un dictionnaire associe des clés à des valeurs : <code>eleve["nom"]</code>.' }],
synthese: ['L’indentation délimite les blocs', 'input() renvoie du texte : convertir avec int() ou float()', 'for quand on connaît la séquence, while sinon', 'Une fonction = paramètres + return + tests'],
qcm: [
['Que vaut 7 // 2 ?', ['3.5', '3', '4', '1'], 1, '// est la division entière.'],
['Que vaut 7 % 2 ?', ['1', '3', '3.5', '0'], 0, '% donne le reste.'],
['Combien de tours fait for i in range(2, 10, 3) ?', ['2', '3', '4', '8'], 1, 'i prend 2, 5, 8.'],
['Que renvoie input() ?', ['Un int', 'Un str', 'Un float', 'Un bool'], 1, 'Toujours une chaîne.'],
['Que vaut notes[-1] pour notes = [12, 15, 9] ?', ['12', '15', '9', 'Erreur'], 2, '-1 désigne le dernier élément.'],
['Que fait return dans une fonction ?', ['Affiche une valeur', 'Renvoie une valeur et sort de la fonction', 'Recommence la fonction', 'Rien'], 1, 'return termine la fonction avec un résultat.'],
['Quelle boucle convient pour « redemander tant que la saisie est invalide » ?', ['for', 'while', 'range', 'if'], 1, 'On ne connaît pas le nombre de tours.'],
['Que produit "3" + "4" ?', ['7', '"34"', 'Erreur', '"7"'], 1, 'Concaténation de chaînes.']],
td: [
{ n: 'Échauffement', c: 'Écrire un programme qui demande l’année de naissance et affiche l’âge en 2026.', r: 'annee = int(input("Année : "))\nprint(2026 - annee)' },
{ n: 'Application', c: 'Écrire est_pair(n) qui renvoie True si n est pair, puis afficher les nombres pairs de 1 à 30.', r: 'def est_pair(n):\n return n % 2 == 0\n\nfor i in range(1, 31):\n if est_pair(i):\n print(i)' },
{ n: 'Application', c: 'Écrire mention(note) qui renvoie « TB », « B », « AB », « Passable » ou « Insuffisant ».', r: 'def mention(n):\n if n >= 16: return "TB"\n if n >= 14: return "B"\n if n >= 12: return "AB"\n if n >= 10: return "Passable"\n return "Insuffisant"' },
{ n: 'Approfondissement', c: 'Écrire maximum(liste) sans utiliser max(), avec ses tests.', r: 'def maximum(l):\n m = l[0]\n for x in l:\n if x > m:\n m = x\n return m\n\nassert maximum([3, 9, 2]) == 9' },
{ n: 'Approfondissement', c: 'Compter le nombre d’occurrences de chaque mot d’une phrase avec un dictionnaire.', r: 'compte = {}\nfor mot in phrase.split():\n compte[mot] = compte.get(mot, 0) + 1' }],
tp: { type: 'IDE Python', url: 'apercu-ide.html?ex=py-pair', desc: 'Exercices corrigés par des tests automatiques, directement dans le navigateur.', etapes: ['Parité et multiples', 'Somme et moyenne d’une liste', 'Compter les voyelles', 'Jeu du nombre mystère', 'Défi : FizzBuzz'] },
plusLoin: [['France-IOI · parcours Python', 'https://www.france-ioi.org/'], ['HackerRank · Python', 'https://www.hackerrank.com/domains/python'], ['DataCamp · Introduction to Python', 'https://www.datacamp.com/courses/intro-to-python-for-data-science']] },
{ id: 'web', match: /HTML|CSS|Le Web|HTTP|serveur web|Apache/i,
titre: 'Le Web : HTTP, HTML, CSS et serveur web', duree: '5 h (CM 1 h 30 · TD 1 h 30 · TP 2 h)', niveau: 'SNT · NSI Première · BTS SIO · BTS CIEL',
prerequis: ['Modèles OSI et TCP/IP (conseillé)'],
competences: ['SNT · Le Web', 'NSI 1re · Interactions entre l’homme et la machine sur le Web', 'BTS SIO · Bloc 1 · Mettre à disposition un service'],
intro: 'Chaque fois que vous ouvrez une page, votre navigateur échange des messages HTTP avec un serveur, puis affiche du HTML mis en forme par du CSS. Comprendre cet échange, c’est pouvoir créer un site, mais aussi le dépanner et le sécuriser.',
cm: [
{ t: 'URL et architecture client-serveur', d: '15 min', html: 'Le <b>client</b> (navigateur) envoie une requête, le <b>serveur</b> (Apache, Nginx) répond. L’URL précise tout : <code>https://www.lycee.fr:443/cours/index.html?id=3</code> = protocole, nom d’hôte, port, chemin, paramètres.' },
{ t: 'Le protocole HTTP', d: '20 min', html: 'HTTP est un protocole texte. La requête contient une méthode, un chemin et des en-têtes ; la réponse contient un code d’état, des en-têtes et un corps.', exemple: 'GET /index.html HTTP/1.1\nHost: www.lycee.fr\n\nHTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\n\n<!doctype html>…', table: [['Code', 'Sens'], ['200', 'OK'], ['301 / 302', 'redirection'], ['403', 'accès interdit'], ['404', 'ressource introuvable'], ['500', 'erreur du serveur']] },
{ t: 'HTML : la structure', d: '20 min', html: 'HTML décrit le sens du contenu avec des balises : titres <code>&lt;h1&gt;</code> à <code>&lt;h6&gt;</code>, paragraphes, listes, liens, images, formulaires. Une page bien structurée est lisible par les moteurs de recherche et les lecteurs d’écran.', exemple: '<!doctype html>\n<html lang="fr">\n<head><meta charset="utf-8"><title>Mon TP</title></head>\n<body>\n <h1>Mon premier site</h1>\n <p>Hébergé sur <a href="https://debian.org">Debian</a>.</p>\n</body>\n</html>' },
{ t: 'CSS : la présentation', d: '20 min', html: 'Une règle CSS associe un sélecteur à des déclarations. Sélecteurs : balise (<code>p</code>), classe (<code>.carte</code>), identifiant (<code>#menu</code>). La mise en page moderne repose sur <code>display: flex</code> et <code>display: grid</code>.', exemple: '.carte {\n border: 2px solid #000;\n padding: 16px;\n}\n.grille { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }' },
{ t: 'Formulaires : GET et POST', d: '10 min', html: 'Un formulaire envoie des données au serveur. <b>GET</b> les place dans l’URL (recherche, filtres). <b>POST</b> les place dans le corps de la requête (connexion, envoi de fichier).', attention: 'Un mot de passe ne doit jamais passer en GET : il finirait dans l’historique et les journaux du serveur.' },
{ t: 'Héberger : le serveur web', d: '15 min', html: 'Sous Debian, <code>apt install apache2</code> installe le serveur ; les pages sont dans <code>/var/www/html</code>, la configuration dans <code>/etc/apache2</code>, les journaux dans <code>/var/log/apache2</code>. <b>HTTPS</b> ajoute TLS et un certificat (Let’s Encrypt).' }],
synthese: ['Client → requête HTTP → serveur → réponse avec code', 'HTML = structure, CSS = présentation', 'GET dans l’URL, POST dans le corps', 'Apache : /var/www/html et /var/log/apache2'],
qcm: [
['Que signifie le code 403 ?', ['Introuvable', 'Accès interdit', 'Erreur serveur', 'Redirection'], 1, '403 Forbidden.'],
['Quelle partie de l’URL est ?id=3 ?', ['Le chemin', 'Les paramètres', 'Le port', 'Le protocole'], 1, 'La chaîne de requête.'],
['Quelle balise pour le titre principal ?', ['<title>', '<h1>', '<head>', '<header>'], 1, '<title> est le titre de l’onglet, <h1> celui de la page.'],
['Quel sélecteur CSS cible class="carte" ?', ['#carte', '.carte', 'carte', '*carte'], 1, 'Le point cible une classe.'],
['Pour un formulaire de connexion, on utilise :', ['GET', 'POST', 'PUT', 'HEAD'], 1, 'Les identifiants ne doivent pas apparaître dans l’URL.'],
['Où Apache sert-il les pages par défaut sous Debian ?', ['/etc/apache2', '/var/www/html', '/home/www', '/srv/http'], 1, 'DocumentRoot par défaut.'],
['Quel port utilise HTTPS ?', ['80', '443', '8080', '22'], 1, 'HTTP 80, HTTPS 443.']],
td: [
{ n: 'Échauffement', c: 'Décomposer https://ent.lycee.fr:8443/notes?eleve=12 : protocole, hôte, port, chemin, paramètres.', r: 'https · ent.lycee.fr · 8443 · /notes · eleve=12' },
{ n: 'Application', c: 'Écrire une page HTML avec un titre, une liste de 3 TP et un lien vers le lycée.', r: '<h1>Mes TP</h1>\n<ul><li>Terminal</li><li>Droits</li><li>Apache</li></ul>\n<a href="https://…">Mon lycée</a>' },
{ n: 'Application', c: 'Écrire le CSS pour afficher 3 cartes côte à côte, avec une bordure noire.', r: '.grille { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }\n.carte { border: 2px solid #000; padding: 16px; }' },
{ n: 'Approfondissement', c: 'Avec curl, afficher uniquement les en-têtes de réponse de https://example.org et relever le code et le type de contenu.', r: 'curl -I https://example.org → HTTP/2 200, content-type: text/html' }],
tp: { type: 'Lab web', url: 'apercu-lab-web.html', desc: 'Terminal et navigateur reliés : installer Apache, publier sa page, la voir en direct.', etapes: ['apt install apache2', 'Vérifier le service', 'Remplacer index.html', 'Actualiser le navigateur relié', 'Lire le journal d’accès'] },
plusLoin: [['MDN Web Docs (Mozilla)', 'https://developer.mozilla.org/fr/'], ['freeCodeCamp · Responsive Web Design', 'https://www.freecodecamp.org/']] },
{ id: 'crypto', match: /mot de passe|hachage|chiffrement|crypto|cybers|sécurité des accès|SSH par clé/i,
titre: 'Cryptographie appliquée : hachage, chiffrement, clés', duree: '5 h (CM 2 h · TD 1 h 30 · TP 1 h 30)', niveau: 'BTS SIO · BTS CIEL · BUT R&T Cyber · Master cybersécurité',
prerequis: ['Binaire et hexadécimal', 'Le terminal Linux'],
competences: ['BTS SIO · Bloc 3 · Cybersécurité des services informatiques', 'BTS CIEL · C08 · Sécuriser', 'BUT R&T parcours Cyber · Compétence « Protéger »'],
intro: 'Mots de passe stockés, sites en HTTPS, connexions SSH, signatures de mises à jour : la cryptographie protège presque tout ce que nous faisons en ligne. L’objectif n’est pas de devenir cryptographe, mais de savoir choisir et configurer les bons outils.',
cm: [
{ t: 'Les trois objectifs', d: '10 min', html: '<b>Confidentialité</b> : seul le destinataire lit le message (chiffrement). <b>Intégrité</b> : le message n’a pas été modifié (hachage, MAC). <b>Authenticité</b> : on sait qui l’a envoyé (signature, certificat).' },
{ t: 'Les fonctions de hachage', d: '20 min', html: 'Une fonction de hachage produit une empreinte de taille fixe. Elle est à sens unique, et un seul bit changé en entrée change complètement l’empreinte. Usages : vérifier un fichier téléchargé, stocker un mot de passe, signer.', exemple: '$ echo -n "bonjour" | sha256sum\n2cb4b1431b84ec15d35ed83bb927e27e8967d75f4bcd9cc4b25c8d879ae23e18\n$ echo -n "Bonjour" | sha256sum\n9172e8eec99f144f72eca9a568759580edadb2cfd154857f07e657569493bc44', attention: 'MD5 et SHA-1 sont cassés (collisions) : ne plus les utiliser pour la sécurité.' },
{ t: 'Stocker un mot de passe', d: '20 min', html: 'On ne stocke jamais un mot de passe en clair ni chiffré, mais un <b>hachage lent et salé</b>. Le <b>sel</b>, aléatoire et unique par compte, empêche les tables précalculées ; la lenteur (bcrypt, scrypt, Argon2) freine la force brute.', table: [['Méthode', 'Verdict'], ['En clair', 'interdit'], ['MD5 / SHA-1', 'cassé'], ['SHA-256 sans sel', 'insuffisant'], ['bcrypt, Argon2id', 'recommandé']] },
{ t: 'Chiffrement symétrique', d: '15 min', html: 'Une même clé chiffre et déchiffre. <b>AES</b> (128 ou 256 bits) est le standard : très rapide, il chiffre les disques, les fichiers, le trafic une fois la session établie. Le problème est d’échanger la clé de façon sûre.' },
{ t: 'Chiffrement asymétrique', d: '20 min', html: 'Chaque personne possède une paire de clés : la <b>publique</b>, diffusée, et la <b>privée</b>, gardée secrète. On chiffre avec la clé publique du destinataire ; lui seul déchiffre avec sa clé privée. À l’inverse, on <b>signe</b> avec sa clé privée et chacun vérifie avec la clé publique. Algorithmes : RSA, courbes elliptiques (Ed25519).' },
{ t: 'En pratique : HTTPS et SSH', d: '15 min', html: '<b>HTTPS (TLS)</b> : le serveur présente un certificat signé par une autorité ; un échange asymétrique établit une clé de session, puis AES chiffre le trafic. <b>SSH</b> : l’authentification par clé remplace le mot de passe.', exemple: '$ ssh-keygen -t ed25519 -C "eleve@syllabus"\n$ ssh-copy-id eleve@192.168.10.10\n$ ssh eleve@192.168.10.10 # plus de mot de passe demandé' }],
synthese: ['Hachage = sens unique, pour l’intégrité', 'Mots de passe : bcrypt ou Argon2, avec sel', 'Symétrique (AES) rapide, asymétrique (RSA, Ed25519) pour échanger et signer', 'Chiffrer avec la clé publique, signer avec la clé privée'],
qcm: [
['Quel objectif assure une fonction de hachage ?', ['Confidentialité', 'Intégrité', 'Disponibilité', 'Anonymat'], 1, 'Elle détecte toute modification.'],
['Pourquoi ajouter un sel ?', ['Accélérer', 'Rendre chaque hachage unique et empêcher les tables précalculées', 'Chiffrer le mot de passe', 'Compresser'], 1, 'Deux mots de passe identiques n’ont plus la même empreinte.'],
['Quel algorithme est recommandé pour stocker un mot de passe ?', ['MD5', 'SHA-1', 'Argon2id', 'AES'], 2, 'Lent, salé, conçu pour ça.'],
['Pour envoyer un message confidentiel à Alice, on chiffre avec :', ['sa clé privée', 'sa clé publique', 'notre clé publique', 'un hachage'], 1, 'Seule sa clé privée le déchiffrera.'],
['Pour signer un document, on utilise :', ['sa propre clé privée', 'la clé publique du destinataire', 'AES', 'SHA-1'], 0, 'Tout le monde vérifie avec notre clé publique.'],
['Dans HTTPS, les données de la page sont chiffrées avec :', ['RSA uniquement', 'une clé de session symétrique', 'le certificat', 'un hachage'], 1, 'L’asymétrique sert à établir la clé de session.'],
['Quelle commande génère une paire de clés SSH moderne ?', ['ssh-keygen -t ed25519', 'ssh-copy-id', 'openssl md5', 'gpg --hash'], 0, 'Ed25519 est recommandé.']],
td: [
{ n: 'Échauffement', c: 'Pour chaque besoin, dire s’il faut hacher, chiffrer ou signer : stocker les mots de passe, envoyer un bulletin confidentiel, prouver qu’une mise à jour vient bien de l’éditeur.', r: 'hacher (lent, salé) · chiffrer · signer' },
{ n: 'Application', c: 'Vérifier l’intégrité d’une image ISO téléchargée à partir de son fichier SHA256SUMS.', r: 'sha256sum -c SHA256SUMS --ignore-missing' },
{ n: 'Application', c: 'Une base de 10 000 comptes a fuité, hachée en MD5 sans sel. Expliquer les risques et la correction.', r: 'Les mots de passe courants sont retrouvés instantanément (tables arc-en-ciel). Forcer la réinitialisation et passer à Argon2id avec sel.' },
{ n: 'Approfondissement', c: 'Configurer un serveur SSH pour refuser les connexions par mot de passe et celles de root.', r: 'Dans /etc/ssh/sshd_config :\nPasswordAuthentication no\nPermitRootLogin no\npuis systemctl restart ssh' }],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Générer une paire de clés, se connecter sans mot de passe, durcir sshd.', etapes: ['Comparer des hachages SHA-256', 'Générer une clé Ed25519', 'Déposer la clé sur le serveur', 'Désactiver l’authentification par mot de passe', 'Vérifier dans /var/log/auth.log'] },
plusLoin: [['ANSSI · Guide de sélection d’algorithmes cryptographiques', 'https://cyber.gouv.fr/publications/mecanismes-cryptographiques'], ['CNIL · Recommandations sur les mots de passe', 'https://www.cnil.fr/fr/mots-de-passe-une-nouvelle-recommandation-pour-maitriser-sa-securite'], ['Root-Me · challenges cryptanalyse', 'https://www.root-me.org/']] }
]);