Compression

Ce document s'applique à la méthode suivante : API Update (v4) : threatListUpdates.fetch.

À propos de la compression

La compression est une fonctionnalité clé des API Safe Browsing (v4). La compression réduit considérablement les besoins en bande passante, ce qui est particulièrement, mais pas exclusivement, pertinent pour les appareils mobiles. Le serveur de navigation sécurisée prend actuellement en charge la compression Rice. D'autres méthodes de compression pourront être ajoutées ultérieurement.

La compression est définie à l'aide du champ supportedCompressions et de CompressionType. Les clients doivent utiliser les types de compression RICE et RAW. La navigation sécurisée utilise le type COMPRESSION_TYPE_UNSPECIFIED lorsque le type de compression n'est pas défini (la compression RAW sera remplacée).

Le serveur de navigation sécurisée utilise également la compression HTTP standard pour compresser davantage les réponses, quel que soit le type de compression sélectionné, à condition que le client définisse l'en-tête de compression HTTP approprié (voir l'article Wikipédia Compression HTTP).

Compression RICE

Comme indiqué, le serveur de navigation sécurisée prend actuellement en charge la compression de riz (consultez l'article Wikipédia Codage Golomb pour en savoir plus sur le codage Golomb-Rice).

Compression/décompression

L'objet RiceDeltaEncoding représente les données encodées par Rice-Golomb. Il est utilisé pour envoyer des index de suppression compressés ou des préfixes de hachage compressés à quatre octets. (Les préfixes de hachage de plus de quatre octets ne sont pas compressés et sont diffusés au format brut.)

Pour les index de suppression, la liste des index est triée par ordre croissant, puis encodée en delta à l'aide de l'encodage RICE. Pour les ajouts, les préfixes de hachage de 4 octets sont réinterprétés en tant que uint32 Little-endian, triés par ordre croissant, puis encodés en delta à l'aide de l'encodage RICE. Notez la différence de format de hachage entre la compression RICE et RAW: les hachages bruts sont des octets triés de manière lexicographique, tandis que les hachages de riz sont des octets uint32 triés par ordre croissant (après décompression).

Autrement dit, la liste des entiers [1, 5, 7, 13] sera encodée sous la forme 1 (la première valeur) et les deltas [4, 2, 6].

La première valeur est stockée dans le champ firstValue, et les deltas sont encodés à l'aide d'un encodeur Golomb-Rice. Le paramètre Rice k (voir ci-dessous) est stocké dans riceParameter. Le champ numEntries contient le nombre de deltas encodés dans l'encodeur Rice (trois dans notre exemple ci-dessus, et non 4). Le champ encodedData contient les deltas encodés réels.

Encodeur/Décodeur

Dans l'encodeur/décodeur Rice, chaque delta n est encodé sous la forme q et r, où n = (q<<k) + r (ou, n = q * (2**k) + r). k est une constante et un paramètre de l'encodeur/décodeur Rice. Les valeurs de q et r sont encodées dans le flux de bits à l'aide de différents schémas d'encodage.

Le quotient q est encodé en codage unaire suivi d'un 0. Autrement dit, 3 serait encodé sous la forme 1 110, 4 sous la forme 11 110 et 7 sous la forme 1 1111110. Le quotient q est décodé en premier.

Le reste r est encodé à l’aide d’un encodage binaire tronqué. Seuls les k bits les moins significatifs de r sont écrits (et donc lus) à partir du flux de bits. Le reste r est décodé après avoir décodé q.

Encodeur/Décodeur de bits

L'encodeur Rice repose sur un encodeur/décodeur de bits dans lequel des bits uniques peuvent être ajoutés à l'encodeur de bits, c'est-à-dire pour encoder un quotient q dont la longueur ne peut être que de deux bits.

L'encodeur de bits est une liste d'octets (8 bits). Les bits sont définis du bit significatif le plus bas dans le premier octet au bit significatif le plus élevé dans le premier octet. Si tous les bits d'un octet sont déjà définis, un nouvel octet (initialisé à zéro) est ajouté à la fin de la liste d'octets. Si le dernier octet n'est pas entièrement utilisé, ses bits significatifs les plus élevés sont définis sur zéro. Exemple :

Bits ajoutés Encodeur de bits après l'ajout de bits
[]
0 [00000000]
1 [00000010]
1 [00000110]
1,0,1 [00101110]
0,0,0 [00101110, 00000000]
1,1,0 [00101110, 00000110]