Olivier Miakinen
2020-10-20 21:51:57 UTC
Bonjour,
Les entêtes d'un message de courriel (e-mail) ou d'un article usenet
sont censés être en US-ASCII seul, quitte à ce qu'ils soient transformés
en ASCII par un encodage MIME selon le RFC 2047.
Mais il arrive que des logiciels mal configurés envoient des caractères
8-bits dans les entêtes, ce qui pose un problème parce qu'on ne peut
jamais savoir avec certitude dans quel charset on est censé les lire.
Pour les développeurs de logiciels devant recevoir et traiter de tels
messages et en faire quelque chose qui ne fiche pas la pagaille, je
propose trois fonctions, selon le degré de gentillesse qu'on veut
accorder à ces entêtes foireux. Dans chacune, je teste d'abord si
c'est de l'UTF-8 avant de me rabattre sur le CP1252 qui est le Latin1
de Windows (inclut tous les caractères de ISO-8859-1, plus quelques
autres).
=============================================================================
function want_utf8($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", $str, $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "UTF-8", $str), $cs);
}
}
function want_translit($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", iconv("UTF-8", "US-ASCII//TRANSLIT", $str), $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "US-ASCII//TRANSLIT", $str), $cs);
}
}
function want_ignore($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", iconv("UTF-8", "US-ASCII//IGNORE", $str), $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "US-ASCII//IGNORE", $str), $cs);
}
}
=============================================================================
Voici un exemple de programme de test, suivi par le résultat de ce programme.
=============================================================================
$utf8 = "Dom Féranpière©® EUR=€ oe=œ OE=Œ";
$latin9 = iconv("UTF-8", "LATIN9//IGNORE", $utf8);
$cp1252 = iconv("UTF-8", "CP1252//IGNORE", $utf8);
printf("\nStarting string, either in UTF-8, LATIN9 or CP1252:\n");
printf("utf8 = %s\n", $utf8);
printf("latin9 = %s\n", iconv("LATIN9", "UTF-8", $latin9));
printf("cp1252 = %s\n", iconv("CP1252", "UTF-8", $cp1252));
printf("\nFunction want_utf8() if we want to obtain utf8:\n");
want_utf8("utf8", $utf8);
want_utf8("latin9", $latin9);
want_utf8("cp1252", $cp1252);
printf("\nFunction want_translit() to transliterate non ASCII:\n");
want_translit("utf8", $utf8);
want_translit("latin9", $latin9);
want_translit("cp1252", $cp1252);
printf("\nFunction want_ignore() to ignore non ASCII:\n");
want_ignore("utf8", $utf8);
want_ignore("latin9", $latin9);
want_ignore("cp1252", $cp1252);
=============================================================================
Starting string, either in UTF-8, LATIN9 or CP1252:
utf8 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
latin9 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
cp1252 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
Function want_utf8() if we want to obtain utf8:
Dom Féranpière©® EUR=€ oe=œ OE=Œ (utf8)
Dom Féranpière©® EUR=¤ oe=½ OE=¼ (latin9)
Dom Féranpière©® EUR=€ oe=œ OE=Œ (cp1252)
Function want_translit() to transliterate non ASCII:
Dom Feranpiere(C)(R) EUR=EUR oe=oe OE=OE (utf8)
Dom Feranpiere(C)(R) EUR=? oe= 1/2 OE= 1/4 (latin9)
Dom Feranpiere(C)(R) EUR=EUR oe=oe OE=OE (cp1252)
Function want_ignore() to ignore non ASCII:
Dom Franpire EUR= oe= OE= (utf8)
Dom Franpire EUR= oe= OE= (latin9)
Dom Franpire EUR= oe= OE= (cp1252)
=============================================================================
Cordialement,
Les entêtes d'un message de courriel (e-mail) ou d'un article usenet
sont censés être en US-ASCII seul, quitte à ce qu'ils soient transformés
en ASCII par un encodage MIME selon le RFC 2047.
Mais il arrive que des logiciels mal configurés envoient des caractères
8-bits dans les entêtes, ce qui pose un problème parce qu'on ne peut
jamais savoir avec certitude dans quel charset on est censé les lire.
Pour les développeurs de logiciels devant recevoir et traiter de tels
messages et en faire quelque chose qui ne fiche pas la pagaille, je
propose trois fonctions, selon le degré de gentillesse qu'on veut
accorder à ces entêtes foireux. Dans chacune, je teste d'abord si
c'est de l'UTF-8 avant de me rabattre sur le CP1252 qui est le Latin1
de Windows (inclut tous les caractères de ISO-8859-1, plus quelques
autres).
=============================================================================
function want_utf8($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", $str, $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "UTF-8", $str), $cs);
}
}
function want_translit($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", iconv("UTF-8", "US-ASCII//TRANSLIT", $str), $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "US-ASCII//TRANSLIT", $str), $cs);
}
}
function want_ignore($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", iconv("UTF-8", "US-ASCII//IGNORE", $str), $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "US-ASCII//IGNORE", $str), $cs);
}
}
=============================================================================
Voici un exemple de programme de test, suivi par le résultat de ce programme.
=============================================================================
$utf8 = "Dom Féranpière©® EUR=€ oe=œ OE=Œ";
$latin9 = iconv("UTF-8", "LATIN9//IGNORE", $utf8);
$cp1252 = iconv("UTF-8", "CP1252//IGNORE", $utf8);
printf("\nStarting string, either in UTF-8, LATIN9 or CP1252:\n");
printf("utf8 = %s\n", $utf8);
printf("latin9 = %s\n", iconv("LATIN9", "UTF-8", $latin9));
printf("cp1252 = %s\n", iconv("CP1252", "UTF-8", $cp1252));
printf("\nFunction want_utf8() if we want to obtain utf8:\n");
want_utf8("utf8", $utf8);
want_utf8("latin9", $latin9);
want_utf8("cp1252", $cp1252);
printf("\nFunction want_translit() to transliterate non ASCII:\n");
want_translit("utf8", $utf8);
want_translit("latin9", $latin9);
want_translit("cp1252", $cp1252);
printf("\nFunction want_ignore() to ignore non ASCII:\n");
want_ignore("utf8", $utf8);
want_ignore("latin9", $latin9);
want_ignore("cp1252", $cp1252);
=============================================================================
Starting string, either in UTF-8, LATIN9 or CP1252:
utf8 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
latin9 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
cp1252 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
Function want_utf8() if we want to obtain utf8:
Dom Féranpière©® EUR=€ oe=œ OE=Œ (utf8)
Dom Féranpière©® EUR=¤ oe=½ OE=¼ (latin9)
Dom Féranpière©® EUR=€ oe=œ OE=Œ (cp1252)
Function want_translit() to transliterate non ASCII:
Dom Feranpiere(C)(R) EUR=EUR oe=oe OE=OE (utf8)
Dom Feranpiere(C)(R) EUR=? oe= 1/2 OE= 1/4 (latin9)
Dom Feranpiere(C)(R) EUR=EUR oe=oe OE=OE (cp1252)
Function want_ignore() to ignore non ASCII:
Dom Franpire EUR= oe= OE= (utf8)
Dom Franpire EUR= oe= OE= (latin9)
Dom Franpire EUR= oe= OE= (cp1252)
=============================================================================
Cordialement,
--
Olivier Miakinen
Olivier Miakinen