Vous êtes sur la page 1sur 10
26 GNU/Linux Magazine France N°231 ERIC FILIOL [Professcur associé ENSTBS] ans de nombreux pro: blames informatiques, il est nécessaire de déter miner si un ou plusieurs léments figurent dans un ensemble de données de référence, et ce, de maniere rapide (en particulier, en mi nimisant les acc®s disques, ce qui de- vient difficile dans la pratique si Yen- semble de référence est grand). Dans bien des cas, usage classique des lables de hachage ne permet pas un tel traitement, en particulier dans des environnement contraints comme ce- lui du calcul embarqué. Dans cet ar ticle, nous allons présenter une struc ture probabiliste, les filtres de Bloom, permettant de traiter efficacement ce type de probléme. Liidée maitresse est d'introduire une dose acceptable erreurs pour augmenter les perfor mances, tout en gérant les contraintes (Comps et mémoire), mais sans dégra der la solution/décision finale. Aprés la présentation d'une implémentation classique, nous verrons une implé- mentation oplimisée, développée par htips:wwwegnulinuxmag.com Lees filtres de Bloom : un peu de bruit pour beaucoup ! auteur, utlisée dans un probleme de sécurité : la détec- tion de comportements malicieux (malwares ou compor- tements humains suspects) ou de patterns comportemen- taux admis ou interits (par exemple, dans les applications de sécurité ou de prise de décision embarquées) QUELQUES NOTIONS DE COMPLEXITE D’ Pour évaluer la complexité d'un algorithme et surtout comparer deux Pe en Cee eerie tiques » : ce sont celles dont le temps d’exécution influe significative- ‘ment sur le temps total d'exécution d'un algorithme. Ainsi, une addi tion ou une allocation seront considérées comme négligeables, par rap: Pett ee cae ce cutee tee eee Pee en eo eee Se ee eee aoe at Lintérét est surtout de pouvoir comparer Vefficacité de deux algo- rithmes, proposant une solution & un méme probleme. Notons f(n) le Ce at ee ae oe ea On dit qu'une fonction est en 0(g(n)) (ou de ordre de grandeur de 9(n)) s'il existe une constante ¢ telle que f(n) < ¢.g(n). Autrement dit, asymptotiquement (dés que n devient grand), on peut approximer £(n) par g(n) a un facteur prés (dans les faits, ¢ prend en compte la différence de puissance entre deux ordinateurs). Quand g(n) est une fonction polynomiale, le probléme est dit de complexité polynomial PS een ee ee eee ee eT en O(n?) (quand nest grand, les termes n’ et 1 dev négligeables Cee ae eu er ca ay Se eee kee ee ee Coes) Prenons pour exemple le tride n objets. existe deux types d'algorithmes Bee ea en cee oe ee et ee et Brea oun + les algorithmes optimisés (merge et sort par exemple) qui sont en. Dario) On voit que quand n est grand, le tri naif devient impossible a utiliser Cnet e CRE cee ete a timisé, il faut juste 2.16? opérations, soit 10 000 fois moins. Pour plus Perr a Re ee ec emai ete Se ete ce ee Re eens Dee ees sce ee Rs données & traiter pour une donnée de taille n en entrée. Ainsi, pour Ces codes ont été testés sur une machine Linux Debian (78 Wheezy 64 bits, gcc 47.2) et sur un Odroid XU Ubuntu 16.04.2 LTS (Xenial Xerus, acc 5.4.0) ele) LY Stree ene trées, il faut stocker (sa table de vérité) 2 octets. Dans ce cas, il est important Pe ee données considérées mene oe ng CU oe oe ee etd Cerrei rta eer uaa: moire) qui sont considérés selon la na- rere ed ec eee ey De een cy différentes instances d'un probléme sur une donnée d'une certaine taille. Elle n’est donc pas facile a obtenir SRC erat rité reposant sur des problémes com- plexes a résoudre pour un attaquant eT Ren oe cs Pe ee Ree See acy instances doivent étre difficiles & err + Celle dite en « pire cas ». Cest celle du cas le plus défavorable (ce qui peut impliquer qu'une part non négligeable Cee ee cris Re Ms eect ce des problémes oit le risque critique Pee oe Sa ed eee ec dans le pire des cas, on ne peut que PCa Reta poeta) www.ed-diamond.com GNU/Linux Magazine France N°231 Fay rN ROBO QUE & SCIENCE Considérons deux cas pratiques pour illustrer le pro- bleme que nous voulons résoudre. Nous disposons pour chacun deux d'un ensemble de référence § (la base de ré- férence) de taille N + dans le cas du craquage de mots de passe, ilsagit des valeurs de hash des mots de passe : + dans le cas de la détection d'un comportement ma- licieux (malware ou comportement humain suspect, patterns comportementaux autorisés ou interdits..., il Sagit d'un vecteur binaire dans lequel chaque bit dé- crit la présence (valeur & 2) ou Fabsence (valeur 3 0) d'une caractéristique particuliére et dintérét pour le probleme posé. Le probleme a résoudre est alors le suivant: tout nou- veau candidat doit étre testé pour déterminer sil est déja présent dans la base. Dans nos deux cas + dans le cadre d'une attaque par dictionnaire, on teste chaque mot de passe en produisant son hash (par ‘exemple SHAI) et on regarde si le hash est déja connu ; dans ce cas, le mot de passe a été « craqué » (corres: ondance mot de passe/hash valide) ; + dans le cas de comportement malicieux (le cas qui sera développé ici), le vecteur de comportement est ‘construit pour un individu (extraction des caractéris- tiques) et Yon vérifie si le comportement correspon- dant est référencé comme suspect ou non, Le probléme est que souvent, la taille N de ces bases peut étre trés grande (plusieurs dizaines a plusieurs cen- taines de milliers déléments). Le nombre de requétes, peut lui aussi étre trés important (plusieurs millions, par exemple dans le cas du craquage de mots de passe), et ce, dans un contexte souvent oii le probléme doit recevoir une réponse en temps quasi réel (en particulier, dans le cas de la détection d'un comportement suspect. Quelles sont les principales techniques de résolution possibles et leurs forces et faiblesses respectives (on sup- ose que N est trop grand pour étre stocké en mémoire) ? + Chaque valeur testée pouvant étre représentée comme un enti, est possible de trier la base de référence (en N.Log(N) opérations), puis pour chaque requete, faire tne recherche dichotomnique (Log(N) opérations). Pour R requétes, nous avons donc N.Log(N) + R.Log(N). ALGO ‘Asymptotiquement (quand W et R sont trop grands), le nombre d‘opérations devient exorbitant, ainsi que le nombre daceés disque. (On utilise une table de hachage (voir section 1 et [3, sections 6.4 et 6.5)). Le nombre d'opérations est de N (construction de la table de hachage) plus R (lecture dans la table). On fait donc beaucoup mieux en exé- ution. Toutefois en mémoire, la complexité est di- rectement proportionnelle la taille H de la table. En pratique, cette taille devient vite incompatible avec la taille de la mémoire physique (en particulier dans Tembarqué), surtout lorsque la taille W est importante, Uiilser un filtre de Bloom. Lidée est de sigificative- ment diminuer la taille de la table (le filtre proprement dip, en introduisant la possbilté davoir de faux posi- tifs en nombre tr limité, En effet, la construction du filtre permet lors d'une requéte concernant un candidat > avec certitude, daffirmer que le candidat ne f- ‘gure pas dans l'ensemble $ (aucun faux négatif possible) > avec une certaine probabilité p, que le candidat peut étre présent dans Vensemble (faux positif) On gagne en mémoire (de maniere significative) et pour les quelques faux positfs le travail de validation du ‘candidat doit rester de complexité marginale (au pire, en P.R.N.Log(N) opérations pour R requétes). I s'agit donc d'un compromis efficace, permettant de considérablement réduire [a taille d'une table de hachage classique, au prix d'un surcodt marginal de calcul. A titre dexemple, dans Bloom (4] sur un cas pratique (recherche de regles de cé- sure de mots) avec N = 580 008, Ia taille H dune table de hachage est de H = 2 006 000 bits. En acceptant un taux derreur de p = 0,0625, la taille du filtre nest que de H = 300 009 bits, soit prés de 7 fois moins et avec 84 % daccds disque totaux en moins [5] Nous allons donc étudier deux constructions de filtres de Bloom et en détaller les performances. La premigre partie de Farticle repose essentiellement sur la publica- tion originale de Burton H. Bloom (4), La partie histo- rique et les différentes techniques classiques de hashing. ont 616 rédigées avec l'aide du magistral ouvrage de Donald Knuth 3, sections 6.4et 6.5]. Exceptées les libraries ‘murmurhash3 d'Austin Appleby [3], tous les codes pré- sentés ici sont de Fauteur 28 GNU/Linux Magazine France N°231 huips:fwww-gnulinuxmag.com Les filtres de Bloom : un peu de bruit pour beaucoup ! 1. TABLE DE HACHAGE CLASSIQUE : RAPPEL Cette section est pour rappel seulement et pour fournir des éléments de ccomparaison avec les filtres de Bloom, Le lecteur trouvera tous les détails al orithmiques et d'implémentation dans [3 sections 6.4 et 6.5] ou dans [7, cha- pitre 17] et [8, section 76] I existe de nombreuses techniques et variantes pour réaliser et utiliser des tables de hachage. Nous en présenterons deux : une présentée par Bloom [4] 2 titre de comparaison avec ses propres filtres, 'autre, plus classique, appelée table de hachage avec chainage. 1.1 Hachage classique Dans les deux cas, nous disposons d'une table de hachage T de taille H. Sot tune valeur K (une clef qui peut étre une chaine de caractéres, un entier..) de ensemble de référence S. Pour enregistrer K dans la table, nous utilisons une fonction de hachage h de la facon suivante Fig: Table de hachagecasque de 1. On génére h(K) a partir de K avec H(K) € (0... H = 1; 2. Kest stockée dans la case dadresse h(K), soit TIN(K)] = K ebprermier bit pout incur 2 a ce lule est vide ou non, puis les b bits La fonction de hachage nest pas une fonction éponyme, au sens crypto- pour le message). Litilsation de la ‘graphique du terme (pour lesquelles des propriétés trés fortes de sécurité sont table est alors simple cexigées). La seule qualité demandée dans notre cas est de satisfaire le mieux possible une répartition uniforme des adresses produites : chaque élément K _|- On calcule h(K) pour une fonc- doit avoir idéalement la méme probabilité de générer une adresse de hachage tion h donnée. (© last donnie 2. Si TEM(K)] est vide, on stocke Quand on vérifie si un candidat K* est dans 5, i sulft de calculer h(K*) et la valeur 14K (b + 2 bits), sinon de voir si TEN(K*)] contient K* ou non. Le fonctionnement général est décrit oon réitére jusqu’a trouver une en figure 1. cellule vide Quelles sont les fonctions usuellesh utilisées ? len existe de nombreuses, 3. Pour déterminer sik” est dans $ mais les plus courantes sont les suivantes pour une table de taille H [3, see- ou non, on calcule i(k") et on tions 6.4 et 6.5): regarde le contenu de TUh(K')], Siilest vide, K’ n'est pas dans $, sinon on compare les b derniers bits avec ceux de K" + h(K) = K mod H (on transforme la clef K en un entier d'un type au moins gal & celui de H). Le calcul est trés rapide. Il est important de ne pas prendre pour i des puissances de 2 (h(K) ne dépendrait sinon que d'une partie des bits de K), mais plutét des nombres premiers éloignés de puis- sences dest 1.2 Hachage uniforme + h(K) = LHA(K.A = IK.AD)] avec 0 < A < 1. Selon Knuth, la valeurA = avec chainage (¥5 ~ 1)/2 donne de bons résultats. Par exemple, sik = 1234567890 et H = 1 000 000 (pour cette valeur de A) alors h(K) = 43 924 Le principal probléme avec la mé= thode précédente (quelle que soit sa Dans Varticle de Bloom [4], ensemble de référence $ contient N messages de _variante) est que la probabilité de col- b bits (clels) La table T est de taille H > W, chaque cellule contenant b + 1 bits" lisions n'est pas nulle. Autrement dit, www.ed-diamond.com GNU/Linux Magazine France N°231 rN ROBOTIQUE & SCIENCE aus ilest possible davoir K et K* tels que h(K) = h(K"). Augmenter la taille H ne permet que de réduire cette probabilité, au prix d'un coat mémoire exorbitant. Pour gérer le collisions, la technique consiste a utiliser des listes changes, se- Jon le principe décrt en figure 2. Fig. 2; Table de hachage avec chainage En cas de collision, on insére la nouvelle clef concernée dans la lste& Tadresse A(K). Lors d’une consultation de la table & la recherche d'un élément K', on parcourt la liste chainge a Yadresse h(K*). Cette technique permet de réduire au passage la taille H de la table et d'avoir une gestion plus fine de la mémoire. Quelles sont les complexités temps et mémoire pour ce type de hachage ? En fait, il est nécessaire de voir les choses selon le principe du compromis tempsimémoire : pour gagner du temps, il faut augmenter la taille de la table (on diminue le risque de collisions et donc, la longueur moyenne de chaque liste chainée) pour réduire la mémoire requise, il faut calculer plus (ls listes chainées 3 parcourir sont en moyenne plus longues) Pour modéliser cela, on utilise le concept de « facteur de remplissage » de la table, défini par a=N/H (autrement dit, le nombre moyen de clefs stockées dans une chaine ou longueur moyenne d'une liste chainge). Alors, nous avons Je résultat de complexité suivant [3, page S17] + Une recherche infructueuse (le candidat K n’est pas dans $) se fait en 141/4.(exp(2a)-1-2a tests en moyenne. Quand la table est pleine, en moyenne on fait 2,2 tests. + Une recherche positive (Ie candidat K est dans S) se fait en 1¢(2/(B.a)). (exp(2a)-1-2a)+(1/4).0 tests en moyenne. Quand la table est pleine, ‘en moyenne on fait 1,8 test 2. LES FILTRES DE BLOOM Historiquement, il sagit d'une va~ riante de codage superpos¢ (surimposed coding), codage découvert plusieurs an- rnées avant les techniques de hachage et dont le plus céldbre est le Zatocoding de Calvin Mooers, er. 1951 [7]. Le co- dage superposé avait 66 mis au point pour économiser de la place sur des cartes perforées (mécanographie). Le codage consiste 2 attribuer pour chaque atribut un code en forme de pattem de k bits pris parmi m. Un objet étant defini par un ensemble dattributs, on Construt ainsi un code spécifique pour chaque objet. Imaginons qu'un objet X donne (que 'on cherche dans une liste) soit caractérisé par trois atributs A, A, et A, codés respectivement (k = 2, 0 10) par 081000100 100100 et (9090001061. Alors, objet Xestcodé par 01000 v 0000100100 v 9900001001 = oo1e101101 Selon les paramétres k et n ainsi ue le nombre eattributs q maximal autorisé pour chaque objet, ce codage limite considérablement les faux po- sitifs (par exemple, n = 32, k = 3.et 4 = 6 donne une probabilité de faux positifs de 0.060008). 2.1 Principe général Soit un ensemble de référence $ de taille N. Un filtre de Bloom se com- pose de deux éléments. + un tableau Tde booléens de taille H (indexation de @ aM = 1); + de d fonctions de hachage h,,h,, hy telles que h,:5 > [0, H = 11. Autrement dit, & un éément 's de, on associe un entier com- prisen Oct H = 2. 30 GNU/Linux Magazine France N°231 huips:fwww-gnulinuxmag.com Les filtres de Bloom : un peu de bruit pour beaucoup ! {x yz} O[1[O[1[ 1] 1 [OOOO] oO] 1/0] 1 [oo] 110 w Fig. 3 Mustravion du principe da filtre de Bloom: ki, 5 = (x,y, 2). On voit alors que élément w nest pas dans S (source image Wikipedia). Dans une phase initial, lest nécessaire de charger Ten- semble $ dans le tableau T de la maniére suivante : pour tout élément s de $ et pour i de 2 d, on calcule hy(s) et on met TIh,(s)] 22. Pour vérfier si un élément s* est dans $ ou non, alors + soit s* S, alors les d entrées TIh,(s')] sont a 2 pour é allant de 1.4.4 ; + sipour i < d nous avons Tth,(s')] = 0, alors s* €. Diu point de vue calculatoir, dés le premier index 10, est possible de décider. 2.2 Analyse des paramétres ‘Trois param@tres principaux interviennent dans le choix dun filtre de Bloom * Le taux d'erreur admissible. II détermine directement la complexité résiduelle pour déterminer sil s'agit ou non d'un faux positif (post-processing). * La taille H du tableau 7, en bits. Il influe sur Voccu- pation mémoire, + Le nombre d de fonctions de hachage utilisées. Il im- pacte le temps de calcul d'une requéte. I est assez intuitif de comprendre que ces trois para- metres dépendent les uns des autres et que la taille N de ensemble de référence § intervient également. Soit on re- ccherche le compromis optimal, soit on fixe une priorité (ou ‘une contrainte) sur l'un des parametres et Yon détermine les valeurs optimales pour les deux autres. Nous repre- rons ici les résultats et discussions établis par Bloom [4] Dans ce qui suit, log(x) représente le logarithme & base 2 et Un(x) le logarithme naturel 2.2.1 Probabilité de faux positifs Soit @ la proportion de bits 3 0 dans le tableau de taille H aprés avoir inséré les éléments d'un ensemble de réfé- rence de taille N. Nous avons done @=(1-d/H)" Un message s* sera un faux posit si et seulement si les d bits TIh,(s*)] sont 3 1. La probabilité d'un tel mes- sage est donnée par P=(1-)! Par calcul et simplification (on suppose que d << H), nous avons alors P=(1~exp(~dN/H))*. Annoter que cette formule rest précise que pour des rap- ports H/N relativement faibles (en pratique H/N < 8), Pour des rapports plus importants, il faut prendre en compte certaines dépendances statistiques {10} 2.2.2 Taille du tableau En reprenant la formule de P, il est possible alors de dé- terminer la taille H du tableau en fonction de P. Nous avons. donc : H = N.(Log(P)).(Log(e)/(Log().Log(2 - ¢)). La encore, la dépendance vis-a-vis des autres paramétres d et N siexprime via la donnée @. www.ed-diamond.com GNU/Linux Magazine France N°231 31 IA, ROBOTIQUE & SCIENCE aus 2.2.3 Nombre optimal de fonctions de hachage Pour déterminer ce nombre, on cherche la valeur de d qui, 8 para- metres N et H fixés, minimise la pro- babilité P (oujours pour des rapports HN telativement faibles) [1]. Cela se produit pourd = (H/N).Un(2). En ré- injectant cette valeur dans la formule de P. on obtient alors deux résultats intéressants. SHEN, (Un(P)/(Un(2) € HN = -1.44.Log(). Cela représente la quantité optimale d'informa- tion nécessaire par élément de S + Le nombre optimal d de fonctions — de hachage est donné par d= = Ln(P)/Un(2) = -LogiP). Ces deux résultats sont trés forts, car ils montrent que d'une part, pour P fxg, la taille H du filtre est propor tionnelle aN (logique somme toute, mais le facteur de proportionnalité est précisément defini). D'autre part, Je nombre d de fonctions de hachage ne dépend que de la probabilité de fausse alarme P, Autrement dit, dans un cas pratique, c'est le contexte opé- rationnel qui va permettre de fixer P (en particulier, le post-processing) et de la, les autres paramétres 2.3 Application : détection de patterns comportementaux. Nous allons utiliser les filtres de Bloom dans le cadre de la validation cde comportements ou de patiernscom- portementaux (détection de malware, prise de décision dans un algorithme de détection embarqué..). On dis- pose d'une base de patterns compor- tementaux de taille M (comportements autorisés ou interdts, selon le contexte). Un « pattern comportemental » est modélisé comme un vecteur de taille 64, chaque bit représentant un compor- tement basique, présent (bit a 2) ou non (bit & 6). Pour chaque événement, un pattern comportemental est extrait (par le moteur danalyse antivrale, par une application embarquée alimentée par des capteurs..) et on recherche si ce pat- {term est dans la base ou non, Ici, es paraméttes sont +R = 2 420 000 requetes + N= 59 09 comportements de référence. Les contraintes du probléme font que tout faux posit aun impact lourd sur la gestion temps-réel (lemps de post-processing). On veut done minimiser P que Ton fixe en 0(2/R) (un faux positif en moyenne), soit P = 0,0000005, ‘Avec ces containtes, nous avons d = 21 et H = 1 500 069, a partir des for mules des sections précédentes La fonction de hachage de base sera HurmurHash3 [6]. Son prototype est le suivant x64_128(uint64_t key, uint32_t seed Le tableau out contient deux entiers de 64 bits h, (key) et h,(key), key étant la clef lata, ici nos vecteuts de 64 bits [12). Pour générer les autres fonctions de hachage & partir de ces deux valeurs, il existe de nombreuses propositions © dans la littérature. Nous avons opté pour celles proposées dans [13] pour leurs ‘excellentes proprietés statistiques 'uniformité hi(key) = hy(key) + ich,(key) + 4? mod H avec i allant de 1.3 21. Voici le code source (version Debian non optimisée) limité aux parties im portantes, dans un souci de concision. Pour tester Vefficacité des parametres choisis vis-vis du taux de faux positfs, nous avons volontairement pris un ichier de requétes ne contenant aucun élément de Vensemble de référence [...] /* Entéte C classique */ include *murmur.h" define SALT_CONSTANT 0x97C29B3A /* Constante murmurhash3 */ int main(int arge, char * argy[]) ( ‘int8_t * béiltre; ‘uint6l_t ept_in, cpt_out, block: intédt * out, hl, h2, index; uint8_t opt_f, i, flag; FILE * fini, * fin2, * fout; clock_t t1, t2, 3; [whresse8 Initialisations diverses *+titeenes/ /* argv[i] ensenble de référence, argv[2] fichier requéte */ finl = fopen(argy(1], "x"); £in2 = fopen(argv(2], "z"): bfiltre = (uint@_t )calloc(0x200000L, sizeof(uint8_t)): 32 GNU/Linux Magazine France N°231 huips:fwww-gnulinuxmag.com Les filtres de Bloom : un peu de bruit pour beaucoup ! 7 on azrondit H A 0x200000L pour le calcul du modulo */ out = (uinté4_t )ealloc(2, sizeof (uint64_t)); /* Valeurs initiales de hash hi et b2 */ ept_in = OLLU; ept_out = OLLU; t1 = elock(): [+++ Traitement de L'ensenble de référence *##**/ while (fscanf(fin1,"20161X", block) , feof (£in1)) { ept_f = 0; MurmurHash3_x64_128 (block, SALT Cousmat, out); /* Calcul de hi et h2 en fonction de 1a clef */ hl = out (0); h2 = out{1]; for(i = 1;4 < 22;444){ index = (hl + i * h2 + iti) & OxIFFFFFL; /* Ici le modulo se simplifie par un masque, d'oi le choix de la taille de 0x200000L pour H */ /* Vérifie si le bit de coordonnées index vaut 1 ou 0 */ opt_£ += bfiltre[index] ; /* Force 4 1 le bit de coordonnées index bfiltre [index] ) /* On vérifie 1'absence de collisions lors de 1a construction du filtre */ LE(ept_£ == 22) ept_outt+; ept_int+s ) printé ("Nombre @lu\n", cpt_in) ; printé ("Nombre de vecteurs en entrée de collisions = #lu\n", ept_out) : cpt_out = OLLU; 42 = clock() /+0+* Traitement des requétes teennneenaeenn] while (fscané (fin2,"8016LX", cblock) , feof (fin2)){ ept_f = 0; MurmurHash3_x64_128 (block, SALT_ CONSTANT, out) ; ‘hl = out(0) :h2 = out {1}; flag = 0; for(i = 1d < 227444) { index = (hl + i * h2 + iti) & Oxi FFFFFL; /* Si le bit est a zéro on quitte la boucle ; le candidat n'est sGrement pas dans l'ensemble de référence */ Af (!bfiltre[index]) (flag = 1:break;) /* Verifie si le bit de coordonnées index vaut 1 ou 0 */ ept_f += bfiltre[index] ; ) Af (flag) continu if (cpt_£ == 22) cpt_outt+; ) printf ("Nombre de faux positifs = #1u\n", pt_out) ; £3 = clock() [...] /* Fin classique programme */ Et le résultat est donné par ‘Aucun faux positif niest 8 déplorer. Les performances ‘obtenues sont Jes suivantes (sans aucune optimisation) : Linux Debian Linux Odroid Construction du filtre secondes secondes 44 secondes requétes 3. OPTIMISATION ET APPLICATIONS DU FILTRE DE BLOOM Limplémentation précédente, bien quiefficace, peut en- core étre considérée comme naive. Il est possible de faire encore mieux. Nous allons, avec les mémes valeurs de N et de R, réduire la valeur de H, sans toutefois modifier son ‘occupation mémoire, Cela est particuliérement intéressant dans des environnements embarqués. Nous verrons ensuite deux applications du fitre de Bloom pour des opérations sur des fichiers, faciles avec une simple ligne de commande pour un fichier de taille raisonnable, mais qui deviennent impossibles (temps et mémoire sur le disque) quand les fi- chiers deviennent énormes (plusieurs Gio & quelques Tio) www.ed-diamond.com GNU/Linux Magazine France N°231 FEY IA, ROBOTIQUE & SCIENCE ab, 3.1 Une optimisation du filtre de Bloom + pour supprimer les doublons toute valeur déja dans la table sera Ecartée, dans le cas contraire, elle sera imprimée dans un fichier Hest possible de réduire la taille du filtre en observant que les valeurs du tableau sont des octets et que 7 bits sur 8 ne sont pas exploités. On va donc les utiliser [14]. Cette optimisation permet de gagner (hors optimisation par- ticuliére) un peu de temps et de diviser la taille du filtre par 8. Voici les por- pour compter des patterns inter- tions significatives modifiées dans le code précédent venant plusieurs fois, au contraire toute valeur déja dans la table /* ta taille du filtre est réduite d'un facteur 8 au moins */ bfiltre = (uint@_t *)calloc(0x40000L, sizeof (uinté_t)) ; Gone! existence, ne; coWison) [4 7 — sera imprimée dans un fichier. Ce index = (hl +i * h2 + iti) 6 OxLFFFFFL: fichier sera in fine trig (il est sou quo = (index >> 3); vent beaucoup plus petit) avec la sen = (index 6 9); commande sort, puis traité avec /* Force 4 1 le bit de coordonnées rem A 1'index valant quo */ lacommande undg (on noubliera béiltre(quo) |= (1 < rem); pas de rajouter +13 chaque effec- I. pour tenir compte de la pré- sence dans la table). ‘Aucun faux positif n'est & déplorer encore une lois. Les performances obte- rues pour cette version optimisée sont les suivantes (sans aucune optimisation) eo ——_)_ Simple, mais extrsmement elfcace Linux Debian Linux Odroid Construction du file 0.01 secondes 0.056 secondes Traitement des Rrequttes __@.22 secondes 2.148 secondes | - CONCLUSION La puissance des filtres de Bloom est elle que ses utlisations sont désor- 3.2 Applications : quand la ligne de mais nombreuses dans pratiquement commande devient impuissante tous les domaines du traitement de Vinformation et de la sécurité (15). La Imaginons un fichier de logs, de traces activités humaines oulogicills...Chaque — rapidité de traitement les rend parti- ligne représente un patter particulier. Mest fréquent de voulor, sur ce fichier: culigrementiintéressants dans analyse temps-él de flux d'information (deep packet inspection, identification de pat- + ou au contraite, identifier et compter les patterns intervenant plusieurs fois. fers dangereux (URL malicieuses dans Chrome par exemple), synchronisation Bitcoin, analyse de logs Ethereum..). Leur utilisation dans le domaine des bases de données est devenue égale- ment fréquente (Cassandra, Hbase Bigtable, PostgreSQL...) pour opti- miser les opérations de recherche et ainsi, diminuer les accés disque. Les filtres de Bloom sont donc un outil & ne jamais oublier, pour lequel il existe de nombreuses autres variantes et op- timisations [16], souvent un peu plus En revanche avec un filtre de Bloom, traiter pour ces deux opérations un complexes 2 mettre en ceuvre. Notre fichier de plusieurs Gio (cas rencontré par Fauteur) se fait trés rapidement (de souhait est que cet article vous donne quelques seconds a quelques minutes) lest toutefois important de bien choi- envie de les explorer et de vous les ap- sir les bons parametres, proprier facilement. i + supprimer les patterns répétés ; Pour un fichier d'une taille relativement faible, on utilise souvent (par faci- lité, mais aussi du fait de leur puissance) Ces commandes sont vraiment pratiques, mais dés que la taille du fichier devient importante (quelques centaines de Mio, voire plusieurs Gio), elles de~ viennent inutilisables : la parti tri en complexité n.Log(n) pour n objets, la mé- moire disque pour les fichiers temporaires, les accs disques..) consomme des ressources exorbitantes et finalement, le traitement nest simplement pas possible. 34 GNU/Linux Magazine France N°231 huips:fwww-gnulinuxmag.com Les filtres de Bloom : un peu de bruit pour beaucoup ! NOTES & REFERENCES [1] Allusion contraposée a une célébre comédie de William Shakespeare. [2]M. R. GAREY, D. S. JOHNSON, « Computers and Intractability - A Guide to the Theory of NP-Completeness », Freeman, 1979, Le meilleur livre sur la théorie de la complexité. Incontournable ! BID. E, KNUTH, « The Art of Computer Programming, Vol3 Sorting and Searching », Addison Wesley, 1973, [4] B. H. BLOOM, « Space/Time Trade-offs in Hash Coding with Allowable Errors », Communications of the ‘ACM, vol. 13, numero 7, juillet 1970, p. 422 2.426, [5] Les talles données ici peuvent paraitre ridicules, en comparaison des capacités disques, RAM et des vitesses des périphériques actuelles. Il faut se rappeler que le travail de Bloom a été publié en 1970. Les lecteurs les plus ages et heureux possesseurs (dont auteur fait partie) d'un ZX Spectrum Sinclair (1982) ou d'un Apple Ile se rappelleront que l'on ne disposait que de 48 Kio de mémoire RAM (64 Kio pour Apple lle), de processeurs 8 bits lents et de mémoire de masse extrémement lentes. De nos jours, si les ordinateurs sont considérablement plus rapides, la taille des problémes et des données a explosé en plus grande proportion Le travail de Bloom reste donc particuliérement d'actualité [6] A. APPLEBY, « SMhasher », hitps://github.com/aappleby/smhasher ITIC. BLAESS, « Développement systéme sous Linux », Eyrolles, 2016. On ne présente plus ce livre ni son auteur ! [8] W. H. PRESS, S. A. TEUTOLSKY, W. T. VETTERLING, B. P. FLANNERY. « Numerical Recipes in C - The Art of Scientific Computing », Cambridge University Press, 2007. [9] C. MOOERS, « Zatocoding Applied to Mechanical Organization of Knowledge », American Documentation, 2, pp. 20-32, 1951. [10] K. CHRISTENSEN, A. ROGINKSY, M. JIMENO, « A New Analysis of the False Positive Rate of a Bloom Filter », Information Processing Letters, 110(21), pp. 944-949, 2010, [11] P. CAO, « Bloom Filter: the Math » : hitp://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.himl, 1998. [12] Dans le cas de clels de plus de 64 bits, il faut itérer la fonction MurmurHash3 plusieurs fois. En utilisant tune variable statique flag, les variables hI et h2 sont initialisées avec le contenu du tableau out quand flag fest plus nul (flag est nul au premier appel et les variables hi, h2 sont initialisées avec le paramétre seed) [13] A. BRODER, M. MITZENMACHER, « Less Hashing, Same Performance: Building a Better Bloom Filter», Algorithms - ESA 2006, 11021), pp. 456-467, Springer Verlag, 2006. [14] Il est possible de généraliser sur des entiers de 64 bits, avec un gain en termes de performance plus quappréciable [15] A. KIRSCH, M. MITZENMACHER, « Network Applications of Bloom Filter: A Survey », Internet Mathematics, vol.1, Nr 4, pp. 485-509, 2002. [16] L. LUO, D. GUO, R. T. B. MA, O. ROTTENSTREICH, X. LUO, « Optimizing Bloom Filter: Challenges, ‘Solutions and Comparisons », AtXiv repository, 2018 : hitp://arxiv-org/abs/1804.04777 www.ed-diamond.com GNU/Linux Magazine France N°231 35

Vous aimerez peut-être aussi