2008-11-26 5 views
196

Peut-on convertir une chaîne hexadécimale en un tableau d'octets en utilisant une fonction intégrée en C# ou dois-je faire une méthode personnalisée pour cela?Comment puis-je convertir une chaîne hexadécimale en un tableau d'octets?

+1

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

+9

@ mik-T, une chaîne hexadécimale est dans un format comme 219098C10D7 qui tous les deux caractères convertit en un seul octet. votre méthode n'est pas utilisable. – AaA

+2

Cette question ne semble pas être une copie de la question sélectionnée. celui-ci convertit FROM chaîne hexadécimale en tableau d'octets, cependant l'autre question convertit le tableau d'octets en hexadécimal. – AaA

Répondre

386

Voici un exemple sympa 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(); 
} 
+84

** Bon Dieu !! ** Est-ce que vous vous rendez compte comment INEFFICIENT c'est ??? Bien sûr, c'est amusant, mais LINQ est surutilisé pour des choses qui devraient être faites autrement! Le code LINQ requiert .NET 3.5 et nécessite de référencer System.Core (qui pourrait autrement ne pas être nécessaire). Voir l'article en double pour des solutions efficaces. –

+17

Il est probablement censé être amusant, pas efficace – Karsten

+1

Cette réponse a au moins l'avantage d'être capable de compiler. keyAsBytes est indéfini dans l'autre. –

35
public static byte[] ConvertHexStringToByteArray(string hexString) 
{ 
    if (hexString.Length % 2 != 0) 
    { 
     throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString)); 
    } 

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

    return HexAsBytes; 
} 
+0

Ne devrait-il pas être "pour (int index = 0; index Noli

54

je fait quelques recherches et trouvé que byte.Parse est encore plus lent que Convert.ToByte. La conversion la plus rapide que je pourrais trouver utilise environ 15 ticks par octet.

public static byte[] StringToByteArrayFastest(string hex) { 
     if (hex.Length % 2 == 1) 
      throw new Exception("The binary key cannot have an odd number of digits"); 

     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; 
     //For uppercase A-F letters: 
     return val - (val < 58 ? 48 : 55); 
     //For lowercase a-f letters: 
     //return val - (val < 58 ? 48 : 87); 
     //Or the two combined, but a bit slower: 
     //return val - (val < 58 ? 48 : (val < 97 ? 55 : 87)); 
    } 

// fonctionne aussi sur .NET Micro Framework où (en SDK4.3) byte.Parse (chaîne) ne permet que des formats entiers.

+0

Il serait préférable que la fonction GetHexVal soit inline à la place. –

+2

J'ai essayé ça, mais d'une certaine manière c'est un peu plus rapide. Peut-être parce que la différence entre le tas et la pile. – CainKellye

+0

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 nettement plus rapide. Et en général, les opérateurs IL ne devraient-ils pas être plus rapides que les appels de fonction? –

4

Je pense que cela peut fonctionner.

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

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

     return hexres.ToArray(); 
    } 
Questions connexes