Format des cookies sur instinctive.eu
Sur ce site, je propose d'enregistrer des informations dans un cookie pour préremplir le formulaire de commentaire.
Comme on entend tout et n'importe quoi sur les cookies, et comme ça reste des données qui sont chez vous mais son mon contrôle, il me semble que c'est la moindre des choses d'essayer de vous expliquer en quoi consistent ces informations.
Le code source du moteur du présent site est publié sous une licence permissive, et est disponible aussi bien sur github que sur mon fossil personnel, mais je ne vous en imposerai pas la lecture si vous voulez juste savoir ce que je dépose chez vous, fût-ce numériquement.
En résumé, j'enregistre dans un cookie nommé c_info
ce que vous avez
rempli dans les champs nom, adresse e-mail, site web, et le format de
commentaire choisi (historique ou markdown). J'applique plusieurs
transformations à ces données pour faire en sorte qu'elles prennent le
moins de place possible. Lorsque vous chargez une page de mon site avec un
formulaire de commentaire, ces informations sont décodées pour préremplir
le formulaire.
La toute première lettre du cookie identifie la suite de transformations,
pour que si un jour j'en trouve une autre plus efficace, je puisse
distinguer les cookies dans l'ancien format de ceux au nouveau format. Donc
pour le moment, comme il n'existe qu'un seul format, tous les cookies
commencent par A
.
Je vais prendre comme exemple un cookie pour moi : je rentre comme nom « Natacha », pas d'adresse e-mail parce que je ne m'écris jamais à moi-même, le site web « //instinctive.eu/ », et les commentaires au format Markdown. Je me retrouve avec un cookie qui contient la chaîne de caractères « AB+OBEFaNEucVVrOFrHFP3CQCUV ».
Sérialisation
Comme il y a quatre morceaux d'information à faire rentrer dans un seul cookie, la première étape est de les combiner en une seule chaîne de caractères, de sorte qu'il soit possible ensuite de retrouver les quatre morceaux.
J'utilise des petits noms internes pour identifier les formats de
commentaires : legacy-comment
pour les commentaires au format historique,
et comment-markdown
pour les commentaires au format markdown. Ce sont des
identifiants que j'utilise déjà à d'autres endroits du code, ça a été plus
pratique de les reprendre directement.
Les quatre chaines de caractères sont combinées en une seule en en faisant
une S-expression. En clair, s'il n'y a que des lettres et des
chiffres et des caractères « gentils », je les écrits à la suite les uns
des autres, séparés par des espaces. S'il y a des espaces ou de la
ponctuation simple, je mets des guillemets ("
) autour. S'il y a trop de
bizarreries dedans, je mets le nombre d'octets, suivi d'un double-point,
suivi directement du contenu.
Pour gagner de la place, je ne mets pas d'espace à la fin, et je ne mets pas une chaîne vide à la fin, autant ne rien mettre et la laisser vide. Et je les mets dans l'ordre suivant : d'abord le petit nom du format de commentaire, puis le nom, puis l'adresse e-mail, et enfin le site.
Dans mon exemple, ça donne :
comment-markdown Natacha ""//instinctive.eu/
Compression Smaz
Une fois toutes les données rassemblées dans une seule chaîne de caractère, on se retrouve avec quelque chose qui prend pas mal de place, et qui peut contenir n'importe quoi, ce qui n'est pas forcément génial.
Pour assainir la communication et en même temps compresser les données, j'utilise une variante personnelle de l'algorithme Smaz, qui a le mérite d'être simple et efficace sur ce type de données. Pour ceux qui connaissent, je l'ai juste appliqué à des symboles en base-64 au lieu d'octets.
Pour ceux qui ne connaissent pas, c'est plus facile de regarder dans le sens de la décompression, et de se dire qu'en faisant l'inverse on peut compresser.
La compression se fait au moyen d'un dictionnaire fixe : la plupart des
symboles représentent une ou plusieurs lettres, et pour décompresser il
suffit de les remplacer par les lettres que chacun représente. Par exemple,
dans mon cookie, après le A
qui indique le format, il y a un B
, qui
signifie à lui tout seul comment-markdown
, qui est bien le début ce que
je voulais compresser à la fin de la section précédente.
Voici le dictionnaire :
Symbole | Valeur | Signification |
---|---|---|
A | 0 | "legacy-comment " |
B | 1 | "comment-markdown " |
C | 2 | "e" |
D | 3 | "o" |
E | 4 | "a" |
F | 5 | "t" |
G | 6 | "m" |
H | 7 | "c" |
I | 8 | "n" |
J | 9 | " " |
K | 10 | "r" |
L | 11 | "l" |
M | 12 | "g" |
N | 13 | "h" |
O | 14 | "s" |
P | 15 | "i" |
Q | 16 | "." |
R | 17 | "om" |
S | 18 | "p" |
T | 19 | "-" |
U | 20 | "u" |
V | 21 | "/" |
W | 22 | "com" |
X | 23 | "y" |
Y | 24 | "en" |
Z | 25 | "le" |
a | 26 | "ac" |
b | 27 | "f" |
c | 28 | "\"" |
d | 29 | "@" |
e | 30 | "d" |
f | 31 | "ma" |
g | 32 | "b" |
h | 33 | "fr" |
i | 34 | "ro" |
j | 35 | "ou" |
k | 36 | "://" |
l | 37 | "http" |
m | 38 | "blog" |
n | 39 | "gmail" |
o | 40 | "www" |
p | 41 | ".fr" |
q | 42 | "k" |
r | 43 | "in" |
s | 44 | "ri" |
t | 45 | "or" |
u | 46 | " \"" |
v | 47 | "z" |
w | 48 | "on" |
x | 49 | "an" |
y | 50 | "w" |
z | 51 | "net" |
0 | 52 | "x" |
1 | 53 | "j" |
2 | 54 | "re" |
3 | 55 | "v" |
4 | 56 | "ee" |
5 | 57 | "ch" |
6 | 58 | "er" |
7 | 59 | "is" |
8 | 60 | "_" |
9 | 61 | spécial |
+ | 62 | spécial |
/ | 63 | spécial |
Comme tout n'est pas dans le dictionnaire, il y a en plus des symboles spéciaux pour représenter ce qui n'y est pas. Dans mon cookie, après le format de commentaire se trouve mon nom, qui commence par une majuscule, alors qu'il n'y a aucune majuscule dans le dictionnaire.
La façon habituelle de sortir un tas d'octets arbitraire en une suite de symboles base-64 est de faire des groupes de trois octets, ce qui fait 24 bits, et les redécouper en quatre symboles base-64, au moyen des valeurs numériques que j'ai données dans le tableau.
Il se trouve que par mégarde, j'ai fait un redécoupage petit-boutiste, c'est-à-dire que le premier symbole base-64 correspond au six bits de moindre poids dans le premier octet, alors que traditionnellement on le fait dans l'autre sens, en y mettant les six bits de poids fort. Comme je m'en suis rendue compte après avoir écrit à la main tous les cas de test, je n'ai pas eu le courage de le corriger.
Donc lorsqu'il y a un nombre multiple de trois d'octets qu'on ne trouve pas
dans le dictionnaire, je le marque avec le caractère /
suivi du nombre de
blocs moins un (parce que ça ne sert à rien d'avoir zéro bloc), suivi des
blocs en question.
Par exemple, les trois lettres ABC
correspondent aux nombres 65, 66, et
67, c'est-à-dire en binaire petit-boutiste 1000 0010, 0100 0010, et
1100 0010, ce qui est redécoupé en 100000, 100100, 001011, 000010,
c'est-à-dire 1, 9, 52, et 16. Et ça correspond aux symboles BJ0Q
. Avec
l'indicateur qu'il s'agit d'un seul bloc de trois octets, on obtient
/ABJ0Q
. Vous comprenez maintenant pourquoi je ne voulais pas refaire tout
ça juste pour écrire le binaire dans l'autre sens ?
Ensuite il y a la question des séquences d'octets qui ne sont pas multiples de trois, c'est-à-dire lorsqu'on n'arrive pas à remplir un bloc. La méthode traditionnelle est d'ajouter du padding, c'est-à-dire des octets qui ne servent à rien pour compléter le bloc. Étant donné la place que ça gaspille, j'ai préféré faire autrement.
Lorsqu'on n'a qu'un seul octet en trop, il faut de toute façon deux
symboles base-64 pour couvrir tous les huit bits. Mais deux symboles
base-64, ça fait douze bits, on pourrait trouver une utilité aux quatre
bits restants. Genre indiquer le nombre de blocs entiers qui suivent. Et le
tout est précédé du symbole +
pour indiquer que c'est 3n+1 bits.
Par exemple, le N
tout seul dans mon cookie, il a la valeur 78, soit
0111 0010, toujours en binaire petit-boutiste, donc 011100 et 10???? en
base-64. Tout seul, il n'y a pas de bloc supplémentaire, les points
d'interrogation sont des zéros, et on finit avec +OB
. Et pour encoder
NABC
, c'est la même chose mais avec un bloc de plus, le B devient F, et
on retrouve le bloc précédent, pour un total +OFBJ0Q
.
Ça ne compresse pas vraiment, on est d'accord, mais ça reste mieux que le « vrai » base-64 pour faire rentrer tout ça dans des caractères civilisés.
Lorsqu'il y des blocs entiers et deux octets qui restent, c'est le même
principe, avec le symbole 9
pour le marquer, trois symboles base-64 qui
encodent les deux octets et deux bits pour le nombre de blocs entiers qui
suivent. Par exemple AB
devient ainsi 9BJE
.
On se rend bien compte que tout ça ne compresse pas vraiment, parce que ça prend nettement plus de place à l'arrivée. Le principe du système est d'espérer que les éléments du dictionnaire sont suffisamment fréquents pour compenser.
Voici le résultat du décodage de mon cookie (pour rappel
AB+OBEFaNEucVVrOFrHFP3CQCUV
), qui illustre finalement assez
peu de fonctionnalités de ce système :
Cookie | Décodage |
---|---|
A | Système d'encodage décrit ici |
B | comment-markdown |
+ | bloc partiel d'un octet |
OB | N et aucun bloc complet ensuite |
E | a |
F | t |
a | ac |
N | h |
E | a |
u | espace " |
c | " |
V | / |
V | / |
r | in |
O | s |
F | t |
r | in |
H | c |
F | t |
P | i |
3 | v |
C | e |
Q | . |
C | e |
U | u |
V | / |
À partir de là, il me semble qu'on peut assez facilement imaginer comment construire le cookie, et peut-être même entrevoir les difficultés pratiques peu intéressantes pour le faire effectivement.
Commentaires
Pas de commentaire pour le moment.
Poster un commentaire
Autour de cette page
Autour de cet article
- Publié le 4 juillet 2017 à 11h49
- Pas de commentaire
Divers
- Les demi-vérités
- Essai d'un réchaud à induction
- Format des cookies sur instinctive.eu
- Journal d'une apprentie motarde
- Marelle Brisée
- Regret-Driven Decisions
- Resumés de Dresden Files
- …
Derniers articles
Derniers commentaires
- _FrnchFrgg_ dans Journal d'une apprentie motarde, stage n°1
- _FrnchFrgg_ dans Journal d'une apprentie motarde, stage n°1
- Natacha dans Journal d'une apprentie motarde, stage n°1
- Ruxor dans Journal d'une apprentie motarde, stage n°1
- Natacha dans Journal d'une apprentie motarde, bilan 2020
- Ruxor dans Journal d'une apprentie motarde, bilan 2020
- Natacha dans Journal d'une apprentie motarde, bilan 2019
- tth dans Journal d'une apprentie motarde, leçon n°19
- Natacha dans Journal d'une apprentie motarde, leçon n°18
- Ruxor dans Journal d'une apprentie motarde, leçon n°18