2008-09-21 9 views
4

Je travaille sur un port série, transmettant et recevant des données sur du matériel à des données 8 bits. Je voudrais stocker en tant que chaîne pour faciliter la comparaison, et les données prédéfinies sont stockées sous forme de chaîne ou format hexadécimal dans le fichier XML. J'ai découvert que seulement en utilisant Encoding.Default qui est le codage ANSI alors les données 8bit sont converties correctement et facilement réversibles. Le codage ASCII ne fonctionne que pour les données 7 bits, et UTF8 ou UTF7 ne fonctionne pas très bien, puisque j'utilise du caractère de 1 à 255. Encoding.Default serait très bien, mais je lis sur MSDN que cela dépend du paramétrage de la page de code du système d'exploitation, ce qui signifie qu'il peut se comporter différemment sur une page de code différente configurée. J'utilise beaucoup GetBytes() et GetString en utilisant le codage, mais je voudrais une méthode à sécurité intégrée et portable qui fonctionne tout le temps à n'importe quelle configuration. Une idée ou une meilleure suggestion pour cela?Encodage .Net 8 bits

Répondre

13

Latin-1 alias ISO-8859-1 alias codepage 28591 est un codepage utile pour ce scénario, car il mappe des valeurs dans la gamme 128-255 inchangée. Ci-dessous 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 dans l'intervalle de 0 à 255 sont mis en correspondance inchangée:

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; 
} 
+0

Je pense que votre idée était la plus proche. Je vais essayer d'abord. – faulty

9

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

+0

parfois avec série i/o vous voulez envoyer des chaînes de texte entrecoupées de caractères de contrôle. Plus facile à lire si vous utilisez des chaînes. – Joe

+0

@Joe: vous pouvez toujours utiliser ASCIIEncoding pour récupérer la chaîne pour une série d'octets. – user7116

+0

ASCIIEncoding ne fonctionne que dans la plage inférieure de 1-127. – faulty

-2

Vous pouvez utiliser le codage base64 pour convertir des octets en chaîne et inversement. Aucun problème avec les pages de codes ou les caractères bizarres de cette façon, et il sera plus efficace que l'espace hexadécimal.

byte[] toEncode; 
string encoded = System.Convert.ToBase64String(toEncode); 
+0

-1: comment base64 aide-t-il? – Joe

+0

Parce que l'OP veut une représentation textuelle des données binaires qui est facile à convertir et peut être mis en XML. L'encodage Base64 correspond à la facture. –

1

Utilisez la page de code hébreu pour Windows 1255. C'est 8 bits.
Encodage enc = Encoding.GetEncoding ("windows-1255");

Je vous missunderstod quand vous avez écrit « 1-255 », où vous pensiez refereing à des personnages dans codepage 1255.

+1

Je travaille sur le système de base anglais – faulty

2

Je pense que vous devez utiliser un tableau d'octets à la place. À titre de comparaison, vous pouvez utiliser une méthode comme ceci:

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; 
} 
+0

J'ai besoin de travailler avec de la corde et sa fonction intégrée comme IndexOf, Replace, Split et SubString. Similaire au commentaire de joe sur la réponse de lassevk – faulty