Utilisation de C #, quelle est la méthode la plus efficace pour convertir une chaîne contenant des données binaires en un tableau d'octets

StackOverflow https://stackoverflow.com/questions/72176

  •  09-06-2019
  •  | 
  •  

Question

Bien qu'il existe 100 façons de résoudre le problème de la conversion, je me concentre sur les performances.

Si la chaîne ne contient que des données binaires, quelle est la méthode la plus rapide, en termes de performances, pour convertir ces données en octet [] (pas char []) sous C #?

Clarification: Ce ne sont pas des données ASCII, mais des données binaires qui se trouvent dans une chaîne.

Était-ce utile?

La solution

Je ne suis pas sûr que ASCIIEncoding.GetBytes le fasse, car il ne prend en charge que plage 0x0000 à 0x007F .

Vous dites que la chaîne ne contient que des octets. Mais une chaîne .NET est un tableau de caractères et 1 caractère est de 2 octets (car un .NET stocke des chaînes au format UTF16). Vous pouvez donc avoir deux situations pour stocker les octets 0x42 et 0x98:

  1. La chaîne était une chaîne ANSI et contenait des octets. Elle est convertie en chaîne unicode. Les octets seront donc 0x00 0x42 0x00 0x98. (La chaîne est stockée sous la forme 0x0042 et 0x0098)
  2. La chaîne était juste un tableau d'octets que vous avez transtypé ou que vous avez simplement reçu comme chaîne et qui est ainsi devenue les octets suivants 0x42 0x98. (La chaîne est stockée sous la forme 0x9842)

Dans la première situation, le résultat serait 0x42 et 0x3F (ascii pour "B?"). La deuxième situation entraînerait 0x3F (ascii pour "?"). C’est logique, car les caractères sont en dehors de la plage ascii valide et le codeur ne sait pas quoi faire avec ces valeurs.

Alors je me demande pourquoi c'est une chaîne avec des octets?

  • Peut-être qu'il contient un octet codé sous forme de chaîne (par exemple, Base64 )?
  • Peut-être devriez-vous commencer par un tableau de caractères ou un tableau d'octets?

Si vous avez réellement la situation 2 et que vous voulez en extraire les octets, vous devez utiliser le UnicodeEncoding.GetBytes . Parce que cela va renvoyer 0x42 et 0x98.

Si vous souhaitez passer d’un tableau de caractères à un tableau d’octets, le moyen le plus rapide serait Marshaling. Mais ce n’est pas vraiment agréable et utilise une mémoire double.

public Byte[] ConvertToBytes(Char[] source)
{
    Byte[] result = new Byte[source.Length * sizeof(Char)];
    IntPtr tempBuffer = Marshal.AllocHGlobal(result.Length);
    try
    {
        Marshal.Copy(source, 0, tempBuffer, source.Length);
        Marshal.Copy(tempBuffer, result, 0, result.Length);
    }
    finally
    {
        Marshal.FreeHGlobal(tempBuffer);
    }
    return result;
}

Autres conseils

Il n'y a rien de tel comme une chaîne ASCII en C #! Les chaînes toujours contiennent du UTF-16. Ne pas s'en rendre compte pose beaucoup de problèmes. Cela dit, les méthodes mentionnées précédemment fonctionnent car elles considèrent la chaîne comme codée en UTF-16 et transforment les caractères en symboles ASCII.

/ EDIT en réponse à la clarification: comment les données binaires sont-elles entrées dans la chaîne? Les chaînes ne sont pas censées contenir des données binaires (utilisez octet [] pour cela).

Si vous souhaitez passer d'une chaîne à des données binaires, vous devez savoir quel encodage a été utilisé pour convertir les données binaires en une chaîne . Sinon, vous pourriez ne pas vous retrouver avec les données binaires correctes. Ainsi, le moyen le plus efficace est probablement GetBytes () sur une sous-classe Encoding (telle que UTF8Encoding), mais vous devez savoir avec certitude quel encodage.

Le commentaire de Kent Boogaart sur la question initiale résume assez bien la situation. ;]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top