Question

Je travaille sur un port série, en transmettant et en recevant des données à certains matériels en données 8 bits. Je voudrais le stocker sous forme de chaîne pour faciliter la comparaison, et les données prédéfinies sont stockées sous forme de chaîne ou de format hexadécimal dans un fichier xml. J'ai découvert que ce n'est qu'en utilisant Encoding.Default, qui est un codage ANSI, que les données 8 bits sont converties correctement et facilement réversibles. Le codage ASCII ne fonctionnera que pour les données 7 bits, et UTF8 ou UTF7 ne fonctionnera pas bien aussi, car j'utilise des caractères compris entre 1 et 255. Encoding.Default serait très bien, mais j'ai lu sur MSDN qu'il est dépendant du paramètre page de code du système d'exploitation, ce qui signifie qu'il peut se comporter différemment selon la configuration de la page de code. J'utilise abondamment GetBytes () et GetString à l'aide de l'encodage, mais j'aimerais une méthode sécurisée et portable qui fonctionne tout le temps, quelle que soit la configuration. Une idée ou une meilleure suggestion pour cela?

Était-ce utile?

La solution

Latin-1, également appelé ISO-8859-1, également codepage 28591, est une page de codes utile pour ce scénario, car elle mappe les valeurs comprises entre 128 et 255 sans les modifier. Les éléments suivants sont interchangeables:

Encoding.GetEncoding(28591)
Encoding.GetEncoding("Latin1")
Encoding.GetEncoding("iso-8859-1")

Le code suivant illustre le fait que, pour Latin1, contrairement à Encoding.Default, tous les caractères compris entre 0 et 255 sont mappés sans modification:

static void Main(string[] args)
{

    Console.WriteLine("Test Default Encoding returned {0}", TestEncoding(Encoding.Default));
    Console.WriteLine("Test Latin1 Encoding returned {0}", TestEncoding(Encoding.GetEncoding("Latin1")));
    Console.ReadLine();
    return;
}

private static bool CompareBytes(char[] chars, byte[] bytes)
{
    bool result = true;
    if (chars.Length != bytes.Length)
    {
        Console.WriteLine("Length mismatch {0} bytes and {1} chars" + bytes.Length, chars.Length);
        return false;
    }
    for (int i = 0; i < chars.Length; i++)
    {
        int charValue = (int)chars[i];
        if (charValue != (int)bytes[i])
        {
            Console.WriteLine("Byte at index {0} value {1:X4} does not match char {2:X4}", i, (int) bytes[i], charValue);
            result = false;
        }
    }
    return result;
}
private static bool TestEncoding(Encoding encoding)
{
    byte[] inputBytes = new byte[256];
    for (int i = 0; i < 256; i++)
    {
        inputBytes[i] = (byte) i;
    }

    char[] outputChars = encoding.GetChars(inputBytes);
    Console.WriteLine("Comparing input bytes and output chars");
    if (!CompareBytes(outputChars, inputBytes)) return false;

    byte[] outputBytes = encoding.GetBytes(outputChars);
    Console.WriteLine("Comparing output bytes and output chars");
    if (!CompareBytes(outputChars, outputBytes)) return false;

    return true;
}

Autres conseils

Pourquoi ne pas simplement utiliser un tableau d'octets? Il n’aurait aucun des problèmes d’encodage que vous auriez à subir avec l’approche texte.

Je pense que vous devriez plutôt utiliser un tableau d'octets. À titre de comparaison, vous pouvez utiliser une méthode comme celle-ci:

static bool CompareRange(byte[] a, byte[] b, int index, int count)
{
    bool res = true;
    for(int i = index; i < index + count; i++)
    {
        res &= a[i] == b[i];
    }
    return res;
}

Utilisez la page de codes en hébreu pour Windows-1255. Son 8 bits.
Encodage enc = Encoding.GetEncoding ("windows-1255");

Je vous ai mal compris quand vous avez écrit "1-255", je pensais que vous vous référiez aux caractères de la page de code 1255.

Vous pouvez utiliser le codage base64 pour convertir d'octet en chaîne et inversement. Pas de problème avec les pages de code ou les caractères étranges de cette façon, et le gain de place sera réduit au minimum.

byte[] toEncode; 
string encoded = System.Convert.ToBase64String(toEncode);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top