Czy możemy przekonwertować ciąg szesnastkowy na tablicę bajtów za pomocą wbudowanej funkcji w języku C#, czy muszę wykonać niestandardową metodę dla tego?Jak przekonwertować łańcuch szesnastkowy na tablicę bajtów?
Odpowiedz
Oto fajny zabawny przykład 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();
}
** Dobre niebiosa !! ** Czy zdajesz sobie sprawę, jak NIEBEZPIECZNY to jest ??? Oczywiście, jest fajnie, ale LINQ jest nadużywany za rzeczy, które powinny być wykonane inaczej! Kod LINQ wymaga .NET 3.5 i wymaga odniesienia do System.Core (który w innym przypadku nie byłby potrzebny). Zobacz duplikat artykułu, aby uzyskać skuteczne rozwiązania. –
To prawdopodobnie miało być zabawne, nieskuteczne. – Karsten
Ta odpowiedź ma co najmniej dodatkową zaletę, że można ją skompilować. keyAsBytes jest niezdefiniowany w drugim. –
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;
}
Czy nie powinno to być "dla (int index = 0; index
Zrobiłem rozeznanie i okazało się, że byte.Parse jest jeszcze wolniej niż Convert.ToByte. Najszybsza konwersja, jaką mogłem wymyślić, to około 15 znaczników na bajt.
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));
}
// działa również na .NET Micro Framework, gdzie (w SDK4.3) byte.Parse (string) dopuszcza tylko formatów całkowitych.
Byłoby lepiej, gdyby funkcja GetHexVal była wbudowana. –
Próbowałem, ale jakoś to jest nieco szybciej. Może dlatego, że różnica między stertą a stosem. – CainKellye
Hmmm dziwne. Testowałem go z VB.NET 2.0 (2010 kompilator) x86 używając jego potrójnego operatora if() i zdecydowanie szybciej. I generalnie, czy operatorzy IL nie powinni być szybsi niż jakiekolwiek wywołania funkcji? –
Myślę, że to może działać.
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();
}
można łatwo przekonwertować ciąg byte [] w jednym wierszu: var tablicaBitowa = Encoding.ASCII.GetBytes (string_with_your_data); –
@ mik-T, łańcuch szesnastkowy ma format w rodzaju 219098C10D7, który co dwa znaki konwertuje na jeden bajt. Twoja metoda nie nadaje się do użytku. – AaA
To pytanie nie wydaje się być duplikatem wybranego pytania. ten konwertuje FROM szesnastkowy na tablicę bajtową, jednak inne pytanie konwertuje tablicę bajtową na szesnastkową. – AaA