314 votes

Comment puis-je convertir une chaîne hexadécimale en un tableau d'octets ?

Pouvons-nous convertir une chaîne hexadécimale en tableau d'octets en utilisant une fonction intégrée en C# ou dois-je créer une méthode personnalisée pour cela ?

2 votes

Vous pouvez facilement convertir une chaîne en byte[] en une seule ligne : var byteArray = Encoding.ASCII.GetBytes(string_with_your_data);

29 votes

@mik-T, une chaîne hexadécimale est dans un certain format comme 219098C10D7 où chaque deux caractères se convertissent en un seul octet. votre méthode n'est pas utilisable.

4 votes

Cette question ne semble pas être un doublon de la question sélectionnée. celle-ci convertit à PARTIR de chaîne hexadécimale en tableau d'octets, tandis que l'autre question convertit un tableau d'octets en hexadécimal.

553voto

JaredPar Points 333733

Voici un bel exemple amusant de LINQ.

public static byte[] StringToByteArray(string hex) {
    return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
}

190 votes

Mon dieu!! Vous rendez-vous compte à quel point c'est INEFFICACE??? Bien sûr, c'est amusant, mais LINQ est trop souvent utilisé pour des tâches qui devraient être autrement! Le code LINQ nécessite .NET 3.5 et nécessite la référence à System.Core (qui pourrait ne pas être nécessaire autrement). Consultez l'article sur les solutions efficaces pour trouver des alternatives.

37 votes

Il est probablement destiné à être amusant, pas efficace

2 votes

Cette réponse a au moins l'avantage supplémentaire de pouvoir être compilée. keyAsBytes n'est pas défini dans l'autre.

98voto

CainKellye Points 298

J'ai fait des recherches et j'ai découvert que byte.Parse est encore plus lent que Convert.ToByte. La conversion la plus rapide que j'ai pu trouver utilise environ 15 ticks par octet.

 public static byte[] StringToByteArrayFastest(string hex) {
        if (hex.Length % 2 == 1)
            throw new Exception("La clé binaire ne peut pas avoir un nombre impair de chiffres");

        byte[] arr = new byte[hex.Length >> 1];

        for (int i = 0; i < hex.Length >> 1; ++i)
        {
            arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
        }

        return arr;
    }

    public static int GetHexVal(char hex) {
        int val = (int)hex;
        //Pour les lettres A-F en majuscules:
        //return val - (val < 58 ? 48 : 55);
        //Pour les lettres a-f en minuscules:
        //return val - (val < 58 ? 48 : 87);
        //Ou les deux combinés, mais un peu plus lent:
        return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
    }

// fonctionne également sur le .NET Micro Framework où (dans le SDK4.3) byte.Parse(string) ne permet que des formats entiers.

0 votes

Il serait préférable que la fonction GetHexVal soit insérée directement à la place.

2 votes

J'ai essayé cela, mais quelque part c'est légèrement plus rapide. Peut-être en raison de la différence entre le Tas et la Pile.

0 votes

Hmmm étrange. Eh bien, je l'ai testé avec VB.NET 2.0 (compilateur 2010) x86 en utilisant son opérateur ternaire if() et il était définitivement plus rapide en ligne. Et en général, les opérateurs IL ne devraient-ils pas être plus rapides que les appels de fonctions?

57voto

Aswath Krishnan Points 358

Le code suivant convertit la chaîne hexadécimale en un tableau d'octets en analysant la chaîne octet par octet.

public static byte[] ConvertHexStringToByteArray(string hexString)
{
    if (hexString.Length % 2 != 0)
    {
        throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "La clé binaire ne peut pas avoir un nombre impair de chiffres : {0}", hexString));
    }

    byte[] data = new byte[hexString.Length / 2];
    for (int index = 0; index < data.Length; index++)
    {
        string byteValue = hexString.Substring(index * 2, 2);
        data[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
    }

    return data; 
}

0 votes

Est-ce que cela ne devrait pas être « for (int index = 0; index < HexAsBytes.Length; index++) » ?

0 votes

68016101061B4A6019339066204680402042204420400042004040206022‌​6024676DB16 avec cela, je reçois La clé binaire ne peut pas avoir un nombre impair de chiffres

12voto

Rick Points 31

Je pense que cela pourrait fonctionner.

public static byte[] StrToByteArray(string str)
    {
        Dictionary hexindex = new Dictionary();
        for (int i = 0; i <= 255; i++)
            hexindex.Add(i.ToString("X2"), (byte)i);

        List hexres = new List();
        for (int i = 0; i < str.Length; i += 2)            
            hexres.Add(hexindex[str.Substring(i, 2)]);

        return hexres.ToArray();
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X