Source: Scratch Wiki en français


Créer un code de sauvegarde (tutoriel)


Créer un code de sauvegarde (anglais : savecode), c'est permettre à l'utilisateur de revenir à un certain moment de l'utilisation d'un projet, application, document. Tous les fichiers, en passant des images aux applications, sont eux-mêmes des codes de sauvegarde.

Ce tutoriel vous explique comment créer un code de sauvegarde sur Scratch et comment l'ouvrir (l'utiliser).

Info
 Info :
Tout ce tutoriel est disponible en tant que projet, ici : https://scratch.mit.edu/projects/889867811/ .

Principe

Lorsqu'un scratcher utilise un projet, il modifie plusieurs valeurs. Ce sont principalement les variables mais cela peut être aussi des listes, la position d'un sprite ou encore le numéro d'un costume.

Si rien n'est sauvegardé à de l'arrêt du projet, lorsque celui-ci redémarre toutes ces valeurs reprennent leurs valeurs par défaut défini par le créateur du projet, donc toutes ces modifications sont perdues. Faire un code de sauvegarde, c'est convertir les valeurs modifiées en une suite de caractères que le projet pourra ensuite demander pour revenir à l'état qu'il avait lorsqu'il a été arrêté.

Réalisation

Premiers pas

Commençons par quelque chose de très simple. Allez dans votre page mes projets et créez un nouveau projet.

Vous verrez comme d'habitude le Scratch Cat au centre de l'écran.

Entrez ces scripts :

quand le drapeau vert pressé
basculer sur le costume (costume1 v)

quand ce sprite est cliqué
basculer sur le costume (costume2 v)
dire ([numéro v] du costume)

Maintenant, lancez le projet et cliquez sur le Scratch Cat.

Félicitations! Vous venez de faire votre premier code de sauvegarde :

2

.

C'est simple, mais c'est bel et bien un code de sauvegarde. Lancez le projet à nouveau, et le Scratch Cat bascule à nouveau sur le costume1.

quand le drapeau vert pressé
basculer sur le costume (costume1 v)
demander [Code ?] et attendre
basculer sur le costume (réponse)

quand ce sprite est cliqué
basculer sur le costume (costume2 v)
dire ([numéro v] du costume)

Relancez le projet et entrez le code

2

.

Le Scratch Cat retourne alors sur le costume2 qu'il avait lorsqu'il vous a donné le code. C'est évidemment une approche très rudimentaire, mais qui permet de comprendre le principe. Vous venez de demander au projet de retourner à l'état qu'il avait lorsque vous l'avez arrêté.

Approfondir

Penchons-nous maintenant sur les cas où il y a plusieurs paramètres à sauvegarder.

Remplacez le script précédent par le suivant :

quand le drapeau vert pressé
basculer sur le costume (nombre aléatoire entre (1) et (2))
mettre la taille à (nombre aléatoire entre (50) et (150))% de la taille initiale
s'orienter à (nombre aléatoire entre (0) et (360))
aller à (position aléatoire v)

Lancez le projet plusieurs fois. Vous allez voir le Scratch Cat aller à plusieurs endroits, grandir, rapetisser, changer de costume et tourner.

LeSaviezVous
 LeSaviezVous :
La probabilité d'obtenir deux fois le même résultat est très faible.

Nous avons 4, ou plutôt 5, valeurs à sauvegarder (en effet, la position d'un sprite se définit par une abscisse x et une ordonnée y).

Pour commencer, créez une variables « compteur » ainsi que deux listes « sauvegarde » et « code ».

(compteur)(sauvegarde ::list)(code ::list)

Il faut également choisir un élément déclencheur à la sauvegarde, par exemple quand la touche « S » (pour sauvegarde) est pressée.

quand la touche [s v] est pressée

Il faut aussi choisir un caractère qui n'a aucune chance de se trouver dans les valeurs sauvegardées. Par exemple le pont-virgule (;).

Si le point-virgule peut être présent dans l'une des valeurs (comme un texte par exemple) il faut choisir un autre symbole. Si vraiment vous n'avez aucune possibilité, gardez le point-virgule mais vous serez obligé de créer des chaînes de caractère.

Voyons maintenant le script de sauvegarde :

quand la touche [s v] est pressée // élément déclencheur de la sauvegarde
supprimer tous les éléments de la liste [sauvegarde v] //on supprime les éléments d'une éventuelle sauvegarde précédente
supprimer tous les éléments de la liste [code v] //même chose
ajouter ([numéro v] du costume) à [sauvegarde v]::list //on place les valeurs à sauvegarder dans la liste sauvegarde
ajouter (taille) à [sauvegarde v]::list
ajouter (direction) à [sauvegarde v]::list
ajouter (abscisse x) à [sauvegarde v]::list
ajouter (ordonnée y) à [sauvegarde v]::list
ajouter [Votre code est :] à [code v]::list //on commence à écrire le code dans la liste code
ajouter [] à [code v]::list
mettre [compteur v] à (1)
répéter (longueur de [sauvegarde v]) fois //on prend une par une les valeurs de la liste sauvegarde
remplacer l'élément (2) de la liste [code v] par (regrouper (élément (2) de [code v]) et (regrouper (élément (compteur) de [sauvegarde v]) et [;])) //on ajoute chaque valeur dans le code en les séparant par le point-virgule.
ajouter (1) à [compteur v]
fin
montrer la liste [code v] //on affiche la liste code dont la première ligne est «Votre code est :» et la deuxième ligne est le code proprement dit composé des valeurs sauvegardées séparées par le point-virgule.
attendre jusqu'à ce que <souris pressée ?>
cacher la liste [code v]

En exécutant le programme, sur la deuxième ligne de la liste code vous devriez voir quelque chose comme

2;98;40;189;99;

.

C'est votre code. Vous pouvez cliquer dessus et le copier pour le coller ensuite où vous voulez. Voyons maintenant comment l'utiliser. Il faut choisir un nouvel élément déclencheur. Les anglophones utilisent souvent la touche « L » (pour load), nous utiliserons donc la touche « C » (pour charger).

Bien évidemment, si vous voulez faire charger un code dès le lancement du projet, utilisez le bloc quand le drapeau vert pressé.

Voici le script :

quand la touche [c v] est pressée // élément déclencheur de demande du code
demander [Code ?] et attendre //demande du code
supprimer tous les éléments de la liste [sauvegarde v] //on supprime les éléments d'une éventuelle sauvegarde précédente
ajouter [] à [sauvegarde v]::list //on commence à placer la première valeur du code dans la liste sauvegarde
mettre [compteur v] à (1)
répéter (longueur de (réponse)) fois //on prend un par un les caractères du code jusqu'au prochain point-virgule
si <(lettre (compteur) de (réponse)) = [;]> alors //si on arrive au point-virgule
ajouter [] à [sauvegarde v]::list //on passe à la valeur suivante
sinon
remplacer l'élément (longueur de [sauvegarde v]) de la liste [sauvegarde v] par (regrouper (élément (longueur de [sauvegarde v]) de [sauvegarde v]) et (lettre (compteur) de (réponse))) //sinon on ajoute chaque caractère du code dans le dernier élément de la liste sauvegarde.
fin
ajouter (1) à [compteur v]
fin
basculer sur le costume (élément (1) de [sauvegarde v]) //on remet le Scratch Cat à la position sauvegardée
mettre la taille à (élément (2) de [sauvegarde v])% de la taille initiale
s'orienter à (élément (3) de [sauvegarde v])
aller à x:(élément (4) de [sauvegarde v]) y:(élément (5) de [sauvegarde v])

Après avoir copier le code de sauvegarde, relancez le projet en cliquant sur le drapeau vert pour faire bouger le Scratch Cat, puis appuyez sur la touche « C » et entrez le code. Le Scratch Cat revient à la position sauvegardée. Bravo à vous !

Aller plus loin

Nous venons de voir comment créer un code de sauvegarde rudimentaire. Cependant, ce code peut encore fortement être amélioré, afin, par exemple, de supporter le caractère séparateur dans une des valeurs à sauvegarder, ou de crypter le code (le rendre illisible afin d'éviter des modifications manuelles).


Créer des variables

La méthode actuellement utilisée par le script utilise un indexage des éléments. C'est à dire, les données sauvegardées sont données dans un ordre et cet ordre ne peut pas être changé. En utilisant un système de variable, il est possible de mélanger les éléments, de savoir rapidement quelle donnée correspond à quel paramètre, etc.

Mettre un texte dans une string

Utilisez cette page pour comprendre le terme anglais de "string" (corde). Pour résumer, une string est une chaîne de texte où le contenu n'est pas analysé. Le procédé présenté ici propose au contraire d'analyser la string afin de pouvoir y placer tous les symboles possibles(méthode « sans pertes »).

Info
 Info :
string est souvent abrégé str.
Paramètres

Avant de vouloir mettre un texte dans une string, il faut définir pour cette méthode sans pertes deux paramètres :

  • un symbole montrant le début et la fin de la string comme "
  • un symbole permettant d'ignorer les propriétés du caractère qui suit comme §
Exemple

L'idée est de créer une "string" § comme celle-ci... deviendra "L'idée est de créer une §"string§" §§ comme celle-ci...".

Info
 Info :
Le but n'est pas de créer une chaîne de caractère lisible par l'humain mais une string lisible pour le programme.
Réalisation
Encodage
définir Encoder (chaîne) (s. séparateur) (s. casseur) (s. à casser)
mettre [i v] à (1) // un compteur
mettre [symboles à casser v] à (regrouper (s. casseur) et (regrouper (s. à casser) et (s. séparateur)))
mettre [code v] à (s. séparateur)
répéter (longueur de (chaîne)) fois
si <(s. à casser) contient (lettre (i) de (chaîne))> alors
mettre [code v] à (regrouper (code) et (regrouper (s. casseur) et (lettre (i) de (chaîne)))
fin
mettre [code v] à (regrouper (code) et (lettre (i) de (chaîne)))
ajouter (1) à [i v]
fin
mettre [code v] à (regrouper (code) et (s. séparateur))
Info
 Info :
Ici :
  • (chaîne::custom) est la chaîne de caractère à encoder
  • (s. séparateur::custom) est le symbole permettant au programme de vérifier les extrémités d'une chaîne de caractère
  • (s. casseur::custom) est le symbole permettant au programme d'ignorer les effets du symbole suivant
  • (s. à casser::custom) est une valeur optionnelle contenant des symboles à casser (à combiner avec (s. casseur::custom))
Décodage
définir Décoder (string) avec (limites) (casseur) (début)
mettre [lecture v] à []
mettre [j v] à ((début) + <(début) = (0)>) // permet de commencer là où voulu ; un compteur
si < non <(lettre (j) de (string)) = (limites)>> alors
mettre [lecture v] à [Erreur : <str> mal codée (début)]
stop [ce script v]
fin
ajouter (1) à [j v]
répéter jusqu'à ce que <(j) > (longueur de (string))>
si <(lettre (j) de (string)) = (limites)> alors // on détecte la fin d'une string
mettre [ajouté v] à (((j) + (1)) - (début)) // permet de savoir là où la lecture s'est arrêtée, un symbole plus loin
stop [ce script v]
sinon
si <(lettre (j) de (string)) = (casseur)> alors
ajouter (1) à [j v]
fin
mettre [lecture v] à (regrouper (lecture) et (lettre (j) de (string)))
fin
ajouter (1) à [j v]
fin
mettre [lecture v] à [Erreur : <str> mal codée (fin)] // si ce bloc s'exécute, c'est que la string à décoder n'a pas de fin, ou alors elle a été « cassée » par erreur
Combiner avec votre code de sauvegarde

Pour commencer, créez ce bloc personnalisé, sans rafraîchissement d'écran :

définir Sauvegarder

Ensuite, placez-y le script de sauvegarde de votre projet (dans Approfondir) :

définir Sauvegarder
supprimer tous les éléments de la liste [sauvegarde v]
supprimer tous les éléments de la liste [code v]
ajouter ([numéro v] du costume) à [sauvegarde v]::list
ajouter (taille) à [sauvegarde v]::list
ajouter (direction) à [sauvegarde v]::list
ajouter (abscisse x) à [sauvegarde v]::list
ajouter (ordonnée y) à [sauvegarde v]::list
ajouter [Votre code est :] à [code v]::list
ajouter [] à [code v]::list
mettre [compteur v] à (1)
répéter (longueur de [sauvegarde v]) fois
remplacer l'élément (2) de la liste [code v] par (regrouper (élément (2) de [code v]) et (regrouper (élément (compteur) de [sauvegarde v]) et [;]))
ajouter (1) à [compteur v]
fin

Sous le déclencheur, placez le script suivant :

quand la touche [s v] est pressée
Sauvegarder::custom
montrer la liste [code v] // attention à bien placer cette partie là du script ici !
attendre jusqu'à ce que <souris pressée ?>
cacher la liste [code v]

Ensuite, créez le bloc personnalisé, sans rafraîchissement d'écran :

définir Sauvegarder - variable, valeur - (var) (val)
mettre [sauver donnée v] à []
Encoder (var) ["] [§] ()::custom // on encode la variable
mettre [sauver donnée v] à (regrouper (code) et [:])
Encoder (val) ["] [§] ()::custom // on encode sa valeur
mettre [sauver donnée v] à (regrouper (sauver donnée) et (code))
ajouter (sauver donnée) à [sauvegarde v]::list // "var":"valeur"

Il s'agit maintenant d'utiliser ce nouveau bloc :

définir Sauvegarder
supprimer tous les éléments de la liste [sauvegarde v]
supprimer tous les éléments de la liste [code v]
répéter (1) fois // les données à sauvegarder
Sauvegarder - variable, valeur - [# cos] ([numéro v] du costume)::custom
Sauvegarder - variable, valeur - [% cos] (taille)::custom
Sauvegarder - variable, valeur - [posD spr] (direction)::custom
Sauvegarder - variable, valeur - [posX spr] (abscisse x)::custom
Sauvegarder - variable, valeur - [posY spr] (ordonnée y)::custom
fin
ajouter [Votre code est :] à [code v]::list
ajouter [] à [code v]::list
mettre [compteur v] à (1)
répéter (longueur de [sauvegarde v]) fois
remplacer l'élément (2) de la liste [code v] par (regrouper (élément (2) de [code v]) et (regrouper (élément (compteur) de [sauvegarde v]) et [;]))
ajouter (1) à [compteur v]
fin

Et pour finir, il faut désormais permettre à votre programme de lire ce nouveau code. Créons donc un bloc nouveau bloc personnalisé, sans rafraîchissement d'écran :

Info
 Info :
Il est possible de remplacer les listes du bloc par les listes (sauvegarde::list) et (code::list) pour en utiliser le moins possible.
définir Charger (code)
mettre [compteur v] à [1] // on initialise les variables
mettre [charger donnée v] à [Code de sauvegarde chargé (pas d'erreur détectée)]
supprimer tous les éléments de la liste [charger : variable v] // on supprime un possible chargement précédent
supprimer tous les éléments de la liste [charger : valeur v] // même chose
répéter jusqu'à ce que <(compteur) > (longueur de (code))>
      si <(lettre (compteur) de (code)) = ["]> alors // si le séparateur de chaîne est détecté, on peut commencer à lire une valeur
            Décoder (code) avec ["] [§] (compteur)::custom // on décode le champ variable
            ajouter (lecture) à [charger : variable v]::list
            ajouter (ajouté) à [compteur v]  // permet d'aller à la fin de la string lue
             si <non <(lettre (compteur) de (code)) = [:]>> alors
                   mettre [charger donnée v] à [Code de sauvegarde invalide]
                   stop [ce script v]
             fin
            ajouter [1] à [compteur v] // permet de sauter le caractère ":" du code de sauvegarde
            Décoder (code) avec ["] [§] (compteur)::custom // on décode le champ valeur
            ajouter (lecture) à [charger : valeur v]::list
            ajouter (ajouté) à [compteur v]  // permet d'aller à la fin de la string lue
            
      fin
      ajouter [1] à [compteur v]
fin

Et sous le déclencheur :

quand la touche [c v] est pressée
demander [Code ?] et attendre ?
Charger (réponse)::custom
dire (regrouper [(Cliquez pour continuer) | ] et (charger donnée))
attendre jusqu'à ce que <souris pressée ?>
dire []
basculer sur le costume (élément (position de [# cos] dans [charger : variable v]) de [charger : valeur v])
mettre la taille à (élément (position de [% cos] dans [charger : variable v]) de [charger : valeur v])% de la taille initiale
s'orienter à (élément (position de [posD spr] dans [charger : variable v]) de [charger : valeur v])
aller à x:(élément (position de [posX spr] dans [charger : variable v]) de [charger : valeur v]) y:(élément (position de [posY spr] dans [charger : variable v]) de [charger : valeur v])

C'est fini ! Bravo à vous d'être arrivé jusqu'ici !

Info
 Info :
"# cos":"1";"% cos":"146";"posD spr":"102";"posX spr":"-177";"posY spr":"-113";
est un exemple de code de sauvegarde.
Idée
 Idée :
Et pour aller encore plus loin, libre à vous d'ajouter des données au code de sauvegarde, comme par exemple :
  • le nom d'utilisateur du créateur du code de sauvegarde ;
  • la date de la sauvegarde ;
  • un canal de vérification des données ;

Chiffre le code

Multiplier les nombres par un nombre quelconque

Cette méthode permet de chiffrer basiquement les nombres.

Par exemple, si votre variable vaut x, le projet réalise pendant la sauvegarde :

ajouter ((variable) * (2468)) à [sauvegarde v]

Et, bien sûr, après le déchiffrement du code, le projet réalise :

mettre [variable v] à ((variable) / (2468))

Convertir chaque caractère du code en nombre

Cette technique se base sur celle du chiffrement des variables cloud qui n'acceptent que les chiffres.


Ainsi, avec cette technique, le code

2;98;-85;-188;-148;

devient

02660908667008056670010808667001040866

.

Algorithmes de cryptographie

N'importe quel algorithme de cryptographie depuis les anciens chiffrements par substitution (César, Vigenère, etc...) jusqu'aux plus modernes peuvent être utilisés. N'étant pas spécifiques à Scratch, ils ne seront pas développés dans ce tutoriel. Vous trouverez de nombreux projets traitant de ces sujets. N'oubliez pas que certains sont complexes à mettre en œuvre et qu'ils vont beaucoup alourdir votre script pour un résultat assez aléatoire.

Info
 Info :
Même en cryptant un code, tous les utilisateurs pourront le décrypter en utilisant votre projet.

La sécurité d'un code passe alors par d'autres méthodes, notamment le canal de vérification des données.
Cet algorithme, utilisé notamment par des formats d'images pour s'assurer que les données n'ont pas été modifiées à la main, vérifie si les valeurs de sauvegarde sont identiques à celles enregistrées à la base dans différents canaux. Si ce n'est pas le cas, le code refuse de finir le chargement et supprime les données chargées.
Cet algorithme n'est pas infaillible mais rend plus difficile la modification manuelle des données de sauvegarde.

Info
 Info :
La méthode la plus simple pour réaliser un canal est :
  • pour des nombres : faire la somme des valeurs ;
  • pour des textes : faire la somme de la longueur des textes ;
  • pour de la logique : créer une suite binaire.

Notez que plus il y aura de canaux différents dans votre code de sauvegarde, plus il sera difficile de le modifier de manière à ce qu'il marche. Vous pouvez stocker les différents canaux sous forme de variables si vous avez suivi le tutoriel en entier.

Voir aussi

Cet article fait partie de la catégorie des tutos
Tous les articles de cette catégorie :