//Omitted for brevity... I'm sure you get the gistprivatestaticreadonlyint[]NybbleLookup=BuildLookup();privateintParseNybble(char c){if(c >'f'){thrownewArgumentException("Invalid hex digit: "+ c);}int ret =NybbleLookup[c];if(ret ==-1){thrownewArgumentException("Invalid hex digit: "+ c);}return ret;}
Je n'ai pas comparé l'un de ces, et j'ai aucune idée de ce qui serait le plus rapide. La solution actuelle est probablement le plus simple.
pourquoi préférez-vous l'analyse de chaque nybble au lieu d'un octet à la fois? est-ce parce que vous êtes plus efficace en ne créant pas de nouvelles cordes à chaque fois? Oui. Pourquoi pas? C'est efficace, et c'est le genre de code que vous avez seulement besoin d'une fois dans une bibliothèque quelque part. Création n*2 chaînes pour créer un tableau d'octets de longueur n semble assez de gaspillage lorsque l'alternative est donc simple. (Btw, downvoters: les commentaires sont appréciés...) Désolé, la création de n chaînes de caractères, pas de n*2. Mais chacune de ces chaînes sera d'environ 20 octets, ce qui semble plutôt un grand facteur de dilatation. Tous les gen0 bien sûr, mais facilement évitable. +1. J'ai fait mine d'être un peu plus "simple" mais je pense que le vôtre est beaucoup plus efficace. Je vais peut-être intégrer la ParseNybble. Il serait assez facile de le fusionner dans mon code existant.
string hexnum ="0000000F";//Represents 15int value =int.Parse(hexnum,System.Globalization.NumberStyles.HexNumber);
Tout ce que vous avez à vous rappeler de le faire est pour un int à diviser le nombre hexadécimal en groupes de 8 chiffres hex (hexadécimal de 4 bits chacun, et CLR type int est 32 bits, d'où 8 chiffres par int). Il y a aussi un octet.Parse() qui fonctionne de la même, mais passe à deux chiffres hexadécimaux à la fois.
Vous avez encore besoin de les convertir à byte[]. BitConverter le ferait. Si la séquence n'est pas un multiple de sizeof(int)? Ya, c'est pourquoi, dans ma dernière phrase je l'ai mentionné l'octet.Méthode Parse (). Ne fonctionne pas pour les chaînes de la longueur spécifiée dans la question, évidemment.
publicbyte[]ParseHexString(string text){if((text.Length%2)!=0){thrownewArgumentException("Invalid length: "+ text.Length);}if(text.StartsWith("0x",StringComparison.InvariantCultureIgnoreCase)){
text = text.Substring(2);}int arrayLength = text.Length/2;byte[] byteArray =newbyte[arrayLength];for(int i =0; i < arrayLength; i++){
byteArray[i]=byte.Parse(text.Substring(i*2,2),NumberStyles.HexNumber);}return byteArray;}
+1 pour des raisons de simplicité. Bien sûr, d'autres réponses ont une meilleure gestion des caractères et ont de meilleures performances, mais cela résout le problème d'une manière qui est facile pour les débutants à comprendre.
Vous aurez besoin de modifier un peu (par exemple, sauter par-dessus les deux premiers caractères), mais il n'gérer les espaces dans la chaîne:
///<summary>///Decodes a hex string, ignoring all non-hex characters, and stores///the decodes series of bytes into the shared buffer. This returns///the number of bytes that were decoded.///<para>Hex characters are [0-9, a-f, A-F].</para>///</summary>///<param name="hexString">String to parse into bytes.</param>///<param name="buffer">Buffer into which to store the decoded binary data.</param>///<returns>The number of bytes decoded.</returns>privatestaticintDecodeHexIntoBuffer(string hexString,byte[] buffer){int count =0;bool haveFirst =false;bool haveSecond =false;char first ='0';char second ='0';for(int i =0; i < hexString.Length; i++){if(!haveFirst){
first = hexString[i];
haveFirst =char.IsLetterOrDigit(first);//we have to continue to the next iteration//or we will miss characterscontinue;}if(!haveSecond){
second = hexString[i];
haveSecond =char.IsLetterOrDigit(second);}if(haveFirst && haveSecond){string hex =""+ first + second;byte nextByte;if(byte.TryParse(hex,NumberStyles.HexNumber,null,out nextByte)){//store the decoded byte into the next slot of the buffer
buffer[count++]= nextByte;}//reset the flags
haveFirst = haveSecond =false;}}return count;}
En fait, il y a un moyen plus facile de convertir deux caractères à un octet:
///<summary>///This will convert a hex-encoded string to byte data///</summary>///<param name="hexData">The hex-encoded string to convert</param>///<returns>The bytes that make up the hex string</returns>publicstaticbyte[]FromHex(string hexData){List<byte> data =newList<byte>();string byteSet =string.Empty;int stringLen = hexData.Length;int length =0;for(int i =0; i < stringLen; i = i +2){
length =(stringLen - i)>1?2:1;
byteSet = hexData.Substring(i, length);//try and parse the data
data.Add(Convert.ToByte(byteSet,16/*base*/));}//next setreturn data.ToArray();}
Quelque chose comme ceci:
(EDIT: Maintenant légèrement plus efficace - pas de sous-chaînes...)
Il est possible que
ParseNybble
pourrait être plus efficace. Par exemple, un switch/case peut être plus efficace:ou peut-être une recherche de tableau:
Je n'ai pas comparé l'un de ces, et j'ai aucune idée de ce qui serait le plus rapide. La solution actuelle est probablement le plus simple.
Oui. Pourquoi pas? C'est efficace, et c'est le genre de code que vous avez seulement besoin d'une fois dans une bibliothèque quelque part. Création n*2 chaînes pour créer un tableau d'octets de longueur n semble assez de gaspillage lorsque l'alternative est donc simple.
(Btw, downvoters: les commentaires sont appréciés...)
Désolé, la création de n chaînes de caractères, pas de n*2. Mais chacune de ces chaînes sera d'environ 20 octets, ce qui semble plutôt un grand facteur de dilatation. Tous les gen0 bien sûr, mais facilement évitable.
+1. J'ai fait mine d'être un peu plus "simple" mais je pense que le vôtre est beaucoup plus efficace. Je vais peut-être intégrer la ParseNybble. Il serait assez facile de le fusionner dans mon code existant.
OriginalL'auteur Jon Skeet
Envisager de tirer parti d'un Cadre de classe qui déjà expose la capacité à effectuer des hex de conversion, XmlReader par exemple:
utilisation:
OriginalL'auteur Handcraftsman
Simple:
Tout ce que vous avez à vous rappeler de le faire est pour un int à diviser le nombre hexadécimal en groupes de 8 chiffres hex (hexadécimal de 4 bits chacun, et CLR type int est 32 bits, d'où 8 chiffres par int). Il y a aussi un octet.Parse() qui fonctionne de la même, mais passe à deux chiffres hexadécimaux à la fois.
Ya, c'est pourquoi, dans ma dernière phrase je l'ai mentionné l'octet.Méthode Parse ().
Ne fonctionne pas pour les chaînes de la longueur spécifiée dans la question, évidemment.
OriginalL'auteur Kevin Anderson
Quelque chose comme ceci:
OriginalL'auteur MatteKarla
Vous aurez besoin de modifier un peu (par exemple, sauter par-dessus les deux premiers caractères), mais il n'gérer les espaces dans la chaîne:
OriginalL'auteur Erich Mirabal
Lent, mais de façon amusante 😀
-jD
OriginalL'auteur jduncanator
En fait, il y a un moyen plus facile de convertir deux caractères à un octet:
OriginalL'auteur user991629
- Je l'utiliser pour C#, du même code en Java.
OriginalL'auteur djunod