Le 20/08/2013 16:47, Alexandre Bacquart a écrit :
Je suis surpris que les fonctions de hachage de la clé (qui se présenter
typiquement en void *key) se basent sur la seule représentation de
l'objet à hacher plutôt que sur sa valeur.
Question d'efficacité et de versatilité.
Mais, surtout, comment peut-on faire autrement (tout en restant
générique) ?
Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
UTF-machin, tout ça...
Le charset va changer en cours d'exécution du programme ?
420+1 et 422-1 ne sont pas des entiers, ce sont des expressions (peu
importe que la valeur après évaluation soit la même). Evidemment,
admettant que tu hash ces expressions (quelle que soit la manière dont
tu les représentes) et non pas le résultat de leur évaluation (l'entier
421), tu auras deux hash différents. Rien de plus normal.
Mais naturellement que je ne parle pas des chaînes "420+1" ou "422-1".
Il s'agit bien de hacher les _valeurs_ des expressions 420+1 ou 422-1.
Le 20/08/2013 16:47, Alexandre Bacquart a écrit :
Je suis surpris que les fonctions de hachage de la clé (qui se présenter
typiquement en void *key) se basent sur la seule représentation de
l'objet à hacher plutôt que sur sa valeur.
Question d'efficacité et de versatilité.
Mais, surtout, comment peut-on faire autrement (tout en restant
générique) ?
Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
UTF-machin, tout ça...
Le charset va changer en cours d'exécution du programme ?
420+1 et 422-1 ne sont pas des entiers, ce sont des expressions (peu
importe que la valeur après évaluation soit la même). Evidemment,
admettant que tu hash ces expressions (quelle que soit la manière dont
tu les représentes) et non pas le résultat de leur évaluation (l'entier
421), tu auras deux hash différents. Rien de plus normal.
Mais naturellement que je ne parle pas des chaînes "420+1" ou "422-1".
Il s'agit bien de hacher les _valeurs_ des expressions 420+1 ou 422-1.
Le 20/08/2013 16:47, Alexandre Bacquart a écrit :
Je suis surpris que les fonctions de hachage de la clé (qui se présenter
typiquement en void *key) se basent sur la seule représentation de
l'objet à hacher plutôt que sur sa valeur.
Question d'efficacité et de versatilité.
Mais, surtout, comment peut-on faire autrement (tout en restant
générique) ?
Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
UTF-machin, tout ça...
Le charset va changer en cours d'exécution du programme ?
420+1 et 422-1 ne sont pas des entiers, ce sont des expressions (peu
importe que la valeur après évaluation soit la même). Evidemment,
admettant que tu hash ces expressions (quelle que soit la manière dont
tu les représentes) et non pas le résultat de leur évaluation (l'entier
421), tu auras deux hash différents. Rien de plus normal.
Mais naturellement que je ne parle pas des chaînes "420+1" ou "422-1".
Il s'agit bien de hacher les _valeurs_ des expressions 420+1 ou 422-1.
Par contre, on pourrait avoir des bits "inutilisés", ie sizeof(short)=4,
CHAR_BITS=8, et seulement 16 bits utilisés pour code la valeur, et 16 bits
inutilisés. Dans ce cas, la fonction de hash en effet pourrait renvoyer
des valeurs différentes.
Oui, c'est exactement mon souci. Ce qui me gêne, c'est cette note de bas
de page de la Norme :
-------------------------------------------------------------------------
It is possible for objects x and y with the same effective type T to
have the same value when they are accessed as objects of type T, but to
have different values in other contexts. In particular, if == is defined
for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T)) == 0.
-------------------------------------------------------------------------
Ceci dit, dans le code que tu présentes, la fonction hashmapCreate
prend en paramètre une fonction de hash et une fonction d'égalité. C'est
à l'utilisateur de passer en paramètre les fonctions adéquates.
Certes mais je ne vois pas en quoi ça change le problème.
J'imagine que
la fonction de comparaison de clés permet, par exemple si la clé est une
structure (ou un tableau), de comparer les membres.
Mais en effet, si l'utilisateur ne connait pas bien la représentation
mémoire de ses données, il risque de se planter. Mais c'est assez
difficile de programmer en C sans connaitre la représentation
mémoire des données.
Les tables de hachage sont une des fonctionnalités qui fait le plus
défaut à la lib standard du C, c'est presque un motif de divorce que de
ne pas en disposer !
Par contre, on pourrait avoir des bits "inutilisés", ie sizeof(short)=4,
CHAR_BITS=8, et seulement 16 bits utilisés pour code la valeur, et 16 bits
inutilisés. Dans ce cas, la fonction de hash en effet pourrait renvoyer
des valeurs différentes.
Oui, c'est exactement mon souci. Ce qui me gêne, c'est cette note de bas
de page de la Norme :
-------------------------------------------------------------------------
It is possible for objects x and y with the same effective type T to
have the same value when they are accessed as objects of type T, but to
have different values in other contexts. In particular, if == is defined
for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T)) == 0.
-------------------------------------------------------------------------
Ceci dit, dans le code que tu présentes, la fonction hashmapCreate
prend en paramètre une fonction de hash et une fonction d'égalité. C'est
à l'utilisateur de passer en paramètre les fonctions adéquates.
Certes mais je ne vois pas en quoi ça change le problème.
J'imagine que
la fonction de comparaison de clés permet, par exemple si la clé est une
structure (ou un tableau), de comparer les membres.
Mais en effet, si l'utilisateur ne connait pas bien la représentation
mémoire de ses données, il risque de se planter. Mais c'est assez
difficile de programmer en C sans connaitre la représentation
mémoire des données.
Les tables de hachage sont une des fonctionnalités qui fait le plus
défaut à la lib standard du C, c'est presque un motif de divorce que de
ne pas en disposer !
Par contre, on pourrait avoir des bits "inutilisés", ie sizeof(short)=4,
CHAR_BITS=8, et seulement 16 bits utilisés pour code la valeur, et 16 bits
inutilisés. Dans ce cas, la fonction de hash en effet pourrait renvoyer
des valeurs différentes.
Oui, c'est exactement mon souci. Ce qui me gêne, c'est cette note de bas
de page de la Norme :
-------------------------------------------------------------------------
It is possible for objects x and y with the same effective type T to
have the same value when they are accessed as objects of type T, but to
have different values in other contexts. In particular, if == is defined
for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T)) == 0.
-------------------------------------------------------------------------
Ceci dit, dans le code que tu présentes, la fonction hashmapCreate
prend en paramètre une fonction de hash et une fonction d'égalité. C'est
à l'utilisateur de passer en paramètre les fonctions adéquates.
Certes mais je ne vois pas en quoi ça change le problème.
J'imagine que
la fonction de comparaison de clés permet, par exemple si la clé est une
structure (ou un tableau), de comparer les membres.
Mais en effet, si l'utilisateur ne connait pas bien la représentation
mémoire de ses données, il risque de se planter. Mais c'est assez
difficile de programmer en C sans connaitre la représentation
mémoire des données.
Les tables de hachage sont une des fonctionnalités qui fait le plus
défaut à la lib standard du C, c'est presque un motif de divorce que de
ne pas en disposer !
Faire un hash générique se basant sur la représentation des objet en
mémoire via un pointer void* (qui perd toute information sur la nature
de l'objet) est inconcevable.
Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
UTF-machin, tout ça...
Le charset va changer en cours d'exécution du programme ?
Non, mais volontairement c'est possible
et il n'est d'ailleurs pas exclu
d'avoir à utiliser plusieurs encodages... plus généralement si tu
travailles avec une bibliothèque qui va te refiler des chaînes en UTF-8
alors que ta représentation interne est UTF-16 (par exemple, et je ne
parle pas d'utiliser plusieurs bibliothèques).
Faire un hash générique se basant sur la représentation des objet en
mémoire via un pointer void* (qui perd toute information sur la nature
de l'objet) est inconcevable.
Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
UTF-machin, tout ça...
Le charset va changer en cours d'exécution du programme ?
Non, mais volontairement c'est possible
et il n'est d'ailleurs pas exclu
d'avoir à utiliser plusieurs encodages... plus généralement si tu
travailles avec une bibliothèque qui va te refiler des chaînes en UTF-8
alors que ta représentation interne est UTF-16 (par exemple, et je ne
parle pas d'utiliser plusieurs bibliothèques).
Faire un hash générique se basant sur la représentation des objet en
mémoire via un pointer void* (qui perd toute information sur la nature
de l'objet) est inconcevable.
Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
UTF-machin, tout ça...
Le charset va changer en cours d'exécution du programme ?
Non, mais volontairement c'est possible
et il n'est d'ailleurs pas exclu
d'avoir à utiliser plusieurs encodages... plus généralement si tu
travailles avec une bibliothèque qui va te refiler des chaînes en UTF-8
alors que ta représentation interne est UTF-16 (par exemple, et je ne
parle pas d'utiliser plusieurs bibliothèques).
> Faire un hash générique se basant sur la représentation des objet en
> mémoire via un pointer void* (qui perd toute information sur la nature
> de l'objet) est inconcevable.
C'est justement ma question ! J'ai donné un exemple de source (Android)
et en voici d'autres :
http://gcc.gnu.org/svn/gcc/trunk/libiberty/hashtab.c
http://troydhanson.github.io/uthash/
http://inn.eyrie.org/svn/trunk/lib/hashtab.c
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
> Faire un hash générique se basant sur la représentation des objet en
> mémoire via un pointer void* (qui perd toute information sur la nature
> de l'objet) est inconcevable.
C'est justement ma question ! J'ai donné un exemple de source (Android)
et en voici d'autres :
http://gcc.gnu.org/svn/gcc/trunk/libiberty/hashtab.c
http://troydhanson.github.io/uthash/
http://inn.eyrie.org/svn/trunk/lib/hashtab.c
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
> Faire un hash générique se basant sur la représentation des objet en
> mémoire via un pointer void* (qui perd toute information sur la nature
> de l'objet) est inconcevable.
C'est justement ma question ! J'ai donné un exemple de source (Android)
et en voici d'autres :
http://gcc.gnu.org/svn/gcc/trunk/libiberty/hashtab.c
http://troydhanson.github.io/uthash/
http://inn.eyrie.org/svn/trunk/lib/hashtab.c
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
les fonctions de hash dépendent de la nature de l'objet.
les fonctions de hash dépendent de la nature de l'objet.
les fonctions de hash dépendent de la nature de l'objet.
Ceci dit, dans le code que tu présentes, la fonction hashmapCreate
prend en paramètre une fonction de hash et une fonction d'égalité. C'est
à l'utilisateur de passer en paramètre les fonctions adéquates.
Certes mais je ne vois pas en quoi ça change le problème.
Ca change le problème dans le sens où cette interface dit explictement
à l'utilisateur que c'est à lui de donner les fonctions de hash et
de comparaison des clés.
La fonction que tu citais en exemple dans le post initial ne fonctionne
en effet que pour des types vérifiant "égalité logique => égalité binaire".
Ceci dit, dans le code que tu présentes, la fonction hashmapCreate
prend en paramètre une fonction de hash et une fonction d'égalité. C'est
à l'utilisateur de passer en paramètre les fonctions adéquates.
Certes mais je ne vois pas en quoi ça change le problème.
Ca change le problème dans le sens où cette interface dit explictement
à l'utilisateur que c'est à lui de donner les fonctions de hash et
de comparaison des clés.
La fonction que tu citais en exemple dans le post initial ne fonctionne
en effet que pour des types vérifiant "égalité logique => égalité binaire".
Ceci dit, dans le code que tu présentes, la fonction hashmapCreate
prend en paramètre une fonction de hash et une fonction d'égalité. C'est
à l'utilisateur de passer en paramètre les fonctions adéquates.
Certes mais je ne vois pas en quoi ça change le problème.
Ca change le problème dans le sens où cette interface dit explictement
à l'utilisateur que c'est à lui de donner les fonctions de hash et
de comparaison des clés.
La fonction que tu citais en exemple dans le post initial ne fonctionne
en effet que pour des types vérifiant "égalité logique => égalité binaire".
Dans celle là, j'ai bien trouvé une fonction de hash sur les chaines
de caractères, mais c'est tout.
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
De quoi parles-tu ? J'ai trouvé hsearch et ses copines, qui fonctionne
juste pour des zero-terminated strings.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
Qu'appelles-tu "insoupçonnable" ? Comme tous les conteneurs C++,
ça t'empèchera de faire une erreur (indétectable avec le void*
en usage en C).
Ensuite, ça te donne des fonctions de hash par défaut pour les
chaines de caractères et les "build-in integral type" (les entiers
pour faire simple). > Mais pour les flottants et les structures,
c'est à l'utilisateur de fournir la fonction de hash.
Dans celle là, j'ai bien trouvé une fonction de hash sur les chaines
de caractères, mais c'est tout.
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
De quoi parles-tu ? J'ai trouvé hsearch et ses copines, qui fonctionne
juste pour des zero-terminated strings.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
Qu'appelles-tu "insoupçonnable" ? Comme tous les conteneurs C++,
ça t'empèchera de faire une erreur (indétectable avec le void*
en usage en C).
Ensuite, ça te donne des fonctions de hash par défaut pour les
chaines de caractères et les "build-in integral type" (les entiers
pour faire simple). > Mais pour les flottants et les structures,
c'est à l'utilisateur de fournir la fonction de hash.
Dans celle là, j'ai bien trouvé une fonction de hash sur les chaines
de caractères, mais c'est tout.
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
De quoi parles-tu ? J'ai trouvé hsearch et ses copines, qui fonctionne
juste pour des zero-terminated strings.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
Qu'appelles-tu "insoupçonnable" ? Comme tous les conteneurs C++,
ça t'empèchera de faire une erreur (indétectable avec le void*
en usage en C).
Ensuite, ça te donne des fonctions de hash par défaut pour les
chaines de caractères et les "build-in integral type" (les entiers
pour faire simple). > Mais pour les flottants et les structures,
c'est à l'utilisateur de fournir la fonction de hash.
candide writes:les fonctions de hash dépendent de la nature de l'objet.
C'est a ma connaissance le cas partout. C'est le cas en C++, c'est le
cas en Java, c'est le cas en Ada. Il peut t'etre fournis des fonctions
qui traitent une serie plus ou moins grande de cas particulier,
tu peux
en avoir une par defaut qui utilise les capacites d'introspection du
langage pour fonctionner mieux dans plus de cas qu'en C, tu peux en
avoir une generee automatiquement qui va fonctionner sous certaines
hypotheses, mais par nature une fonction de hachage va dependre de la
notion d'egalite desiree et il te faudra pouvoir specifier cette notion
d'une maniere ou d'une autre (tu peux disposer d'annotations utilisees
par la fonction introspective ou par le generateur pour traiter de cas
simples comme simplement ignorer un champs).
candide <candide@free.invalid> writes:
les fonctions de hash dépendent de la nature de l'objet.
C'est a ma connaissance le cas partout. C'est le cas en C++, c'est le
cas en Java, c'est le cas en Ada. Il peut t'etre fournis des fonctions
qui traitent une serie plus ou moins grande de cas particulier,
tu peux
en avoir une par defaut qui utilise les capacites d'introspection du
langage pour fonctionner mieux dans plus de cas qu'en C, tu peux en
avoir une generee automatiquement qui va fonctionner sous certaines
hypotheses, mais par nature une fonction de hachage va dependre de la
notion d'egalite desiree et il te faudra pouvoir specifier cette notion
d'une maniere ou d'une autre (tu peux disposer d'annotations utilisees
par la fonction introspective ou par le generateur pour traiter de cas
simples comme simplement ignorer un champs).
candide writes:les fonctions de hash dépendent de la nature de l'objet.
C'est a ma connaissance le cas partout. C'est le cas en C++, c'est le
cas en Java, c'est le cas en Ada. Il peut t'etre fournis des fonctions
qui traitent une serie plus ou moins grande de cas particulier,
tu peux
en avoir une par defaut qui utilise les capacites d'introspection du
langage pour fonctionner mieux dans plus de cas qu'en C, tu peux en
avoir une generee automatiquement qui va fonctionner sous certaines
hypotheses, mais par nature une fonction de hachage va dependre de la
notion d'egalite desiree et il te faudra pouvoir specifier cette notion
d'une maniere ou d'une autre (tu peux disposer d'annotations utilisees
par la fonction introspective ou par le generateur pour traiter de cas
simples comme simplement ignorer un champs).
Oui, c'est exactement mon souci. Ce qui me gêne, c'est cette note de bas
de page de la Norme :
-------------------------------------------------------------------------
It is possible for objects x and y with the same effective type T to
have the same value when they are accessed as objects of type T, but to
have different values in other contexts. In particular, if == is defined
for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T)) == 0.
-------------------------------------------------------------------------
Oui. Le cas doit être extrèmement rare avec des entiers, plus commun
avec les flottants.
Mais ce sont surtout les structures qui sont le cas courant, puisqu'on
peut faire x= y et avoir ensuite memcmp(&x, &y, sizeof (T)) != 0.
Oui, c'est exactement mon souci. Ce qui me gêne, c'est cette note de bas
de page de la Norme :
-------------------------------------------------------------------------
It is possible for objects x and y with the same effective type T to
have the same value when they are accessed as objects of type T, but to
have different values in other contexts. In particular, if == is defined
for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T)) == 0.
-------------------------------------------------------------------------
Oui. Le cas doit être extrèmement rare avec des entiers, plus commun
avec les flottants.
Mais ce sont surtout les structures qui sont le cas courant, puisqu'on
peut faire x= y et avoir ensuite memcmp(&x, &y, sizeof (T)) != 0.
Oui, c'est exactement mon souci. Ce qui me gêne, c'est cette note de bas
de page de la Norme :
-------------------------------------------------------------------------
It is possible for objects x and y with the same effective type T to
have the same value when they are accessed as objects of type T, but to
have different values in other contexts. In particular, if == is defined
for type T, then x == y does not imply that memcmp(&x, &y, sizeof (T)) == 0.
-------------------------------------------------------------------------
Oui. Le cas doit être extrèmement rare avec des entiers, plus commun
avec les flottants.
Mais ce sont surtout les structures qui sont le cas courant, puisqu'on
peut faire x= y et avoir ensuite memcmp(&x, &y, sizeof (T)) != 0.
> Faire un hash générique se basant sur la représentation des objet en
> mémoire via un pointer void* (qui perd toute information sur la nature
> de l'objet) est inconcevable.
C'est justement ma question ! J'ai donné un exemple de source (Android)
et en voici d'autres :
http://gcc.gnu.org/svn/gcc/trunk/libiberty/hashtab.c
http://troydhanson.github.io/uthash/
http://inn.eyrie.org/svn/trunk/lib/hashtab.c
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
>
>>> Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
>>> UTF-machin, tout ça...
>>
>> Le charset va changer en cours d'exécution du programme ?
>
> Non, mais volontairement c'est possible
?
> et il n'est d'ailleurs pas exclu
> d'avoir à utiliser plusieurs encodages... plus généralement si tu
> travailles avec une bibliothèque qui va te refiler des chaînes en UTF-8
> alors que ta représentation interne est UTF-16 (par exemple, et je ne
> parle pas d'utiliser plusieurs bibliothèques).
Ce n'est pas le problème. Si au départ (état A) je place "toto" comme
clé dans ma table de hachage (clé associée à une valeur, par exemple
2013) et que plus tard (état B) je cherche à nouveau "toto" dans ma
table de hachage pour récupérer 2013, la 2ème clé ("toto") sera
obligatoirement égale à la clé de l'état A (par définition d'une chaîne
et de l'égalité de deux chaînes) donc toute fonction de hachage, comme
celle que j'ai donnée dans mon exemple initial, se basant uniquement sur
la _valeur_ arithmétique de l'octet (et pas sa représentation interne)
sera valide. Par contre, si la fonction de hachage utilisait la
représentation interne d'un caractère en faisant par exemple des
décalages, je ne suis pas certain que la fonction serait encore valide
(des clé identiques pourraient avoir des hash différents) sauf peut être
si les caractères sont non signés car alors tous les bits sont des bits
de valeur.
> Faire un hash générique se basant sur la représentation des objet en
> mémoire via un pointer void* (qui perd toute information sur la nature
> de l'objet) est inconcevable.
C'est justement ma question ! J'ai donné un exemple de source (Android)
et en voici d'autres :
http://gcc.gnu.org/svn/gcc/trunk/libiberty/hashtab.c
http://troydhanson.github.io/uthash/
http://inn.eyrie.org/svn/trunk/lib/hashtab.c
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
>
>>> Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
>>> UTF-machin, tout ça...
>>
>> Le charset va changer en cours d'exécution du programme ?
>
> Non, mais volontairement c'est possible
?
> et il n'est d'ailleurs pas exclu
> d'avoir à utiliser plusieurs encodages... plus généralement si tu
> travailles avec une bibliothèque qui va te refiler des chaînes en UTF-8
> alors que ta représentation interne est UTF-16 (par exemple, et je ne
> parle pas d'utiliser plusieurs bibliothèques).
Ce n'est pas le problème. Si au départ (état A) je place "toto" comme
clé dans ma table de hachage (clé associée à une valeur, par exemple
2013) et que plus tard (état B) je cherche à nouveau "toto" dans ma
table de hachage pour récupérer 2013, la 2ème clé ("toto") sera
obligatoirement égale à la clé de l'état A (par définition d'une chaîne
et de l'égalité de deux chaînes) donc toute fonction de hachage, comme
celle que j'ai donnée dans mon exemple initial, se basant uniquement sur
la _valeur_ arithmétique de l'octet (et pas sa représentation interne)
sera valide. Par contre, si la fonction de hachage utilisait la
représentation interne d'un caractère en faisant par exemple des
décalages, je ne suis pas certain que la fonction serait encore valide
(des clé identiques pourraient avoir des hash différents) sauf peut être
si les caractères sont non signés car alors tous les bits sont des bits
de valeur.
> Faire un hash générique se basant sur la représentation des objet en
> mémoire via un pointer void* (qui perd toute information sur la nature
> de l'objet) est inconcevable.
C'est justement ma question ! J'ai donné un exemple de source (Android)
et en voici d'autres :
http://gcc.gnu.org/svn/gcc/trunk/libiberty/hashtab.c
http://troydhanson.github.io/uthash/
http://inn.eyrie.org/svn/trunk/lib/hashtab.c
La glib a bien des tables de hachage mais pas génériques, les fonctions
de hash dépendent de la nature de l'objet.
Faut-il passer au C++ pour disposer d'une table de hachage générique
insoupçonnable ?
>
>>> Ha bon ? Et si l'encodage des chaînes change ? ASCII, EBCDIC,
>>> UTF-machin, tout ça...
>>
>> Le charset va changer en cours d'exécution du programme ?
>
> Non, mais volontairement c'est possible
?
> et il n'est d'ailleurs pas exclu
> d'avoir à utiliser plusieurs encodages... plus généralement si tu
> travailles avec une bibliothèque qui va te refiler des chaînes en UTF-8
> alors que ta représentation interne est UTF-16 (par exemple, et je ne
> parle pas d'utiliser plusieurs bibliothèques).
Ce n'est pas le problème. Si au départ (état A) je place "toto" comme
clé dans ma table de hachage (clé associée à une valeur, par exemple
2013) et que plus tard (état B) je cherche à nouveau "toto" dans ma
table de hachage pour récupérer 2013, la 2ème clé ("toto") sera
obligatoirement égale à la clé de l'état A (par définition d'une chaîne
et de l'égalité de deux chaînes) donc toute fonction de hachage, comme
celle que j'ai donnée dans mon exemple initial, se basant uniquement sur
la _valeur_ arithmétique de l'octet (et pas sa représentation interne)
sera valide. Par contre, si la fonction de hachage utilisait la
représentation interne d'un caractère en faisant par exemple des
décalages, je ne suis pas certain que la fonction serait encore valide
(des clé identiques pourraient avoir des hash différents) sauf peut être
si les caractères sont non signés car alors tous les bits sont des bits
de valeur.