BitConverter.ToString() в обратном порядке?
У меня есть массив байтов, который я хотел бы хранить в виде строки. Я могу сделать это следующим образом:
byte[] array = new byte[] { 0x01, 0x02, 0x03, 0x04 };
string s = System.BitConverter.ToString(array);
// Result: s = "01-02-03-04"
Пока все хорошо. Кто-нибудь знает, как я вернусь к массиву? Не существует перегрузки BitConverter.GetBytes(), которая берет строку, и кажется, что это неприятное обходное решение, чтобы разбить строку на массив строк и затем преобразовать каждый из них.
Рассматриваемый массив может иметь переменную длину, вероятно, около 20 байтов.
Ответы
Ответ 1
Не встроенный метод, а реализация. (Это может быть сделано без раскола, хотя).
String[] arr=str.Split('-');
byte[] array=new byte[arr.Length];
for(int i=0; i<arr.Length; i++) array[i]=Convert.ToByte(arr[i],16);
Метод без разделения: (делает много предположений о формате строки)
int length=(s.Length+1)/3;
byte[] arr1=new byte[length];
for (int i = 0; i < length; i++)
arr1[i] = Convert.ToByte(s.Substring(3 * i, 2), 16);
И еще один метод, без разделения или подстроки. Однако вы можете быть расстреляны, если вы передадите это исходному контролю. Я не несу ответственности за такие проблемы со здоровьем.
int length=(s.Length+1)/3;
byte[] arr1=new byte[length];
for (int i = 0; i < length; i++)
{
char sixteen = s[3 * i];
if (sixteen > '9') sixteen = (char)(sixteen - 'A' + 10);
else sixteen -= '0';
char ones = s[3 * i + 1];
if (ones > '9') ones = (char)(ones - 'A' + 10);
else ones -= '0';
arr1[i] = (byte)(16*sixteen+ones);
}
(в основном реализация преобразования base16 на двух символах)
Ответ 2
Вы можете сами проанализировать строку:
byte[] data = new byte[(s.Length + 1) / 3];
for (int i = 0; i < data.Length; i++) {
data[i] = (byte)(
"0123456789ABCDEF".IndexOf(s[i * 3]) * 16 +
"0123456789ABCDEF".IndexOf(s[i * 3 + 1])
);
}
Самое аккуратное решение, хотя, я считаю, использует расширения:
byte[] data = s.Split('-').Select(b => Convert.ToByte(b, 16)).ToArray();
Ответ 3
Если вам не нужен этот конкретный формат, попробуйте использовать Base64, например:
var bytes = new byte[] { 0x12, 0x34, 0x56 };
var base64 = Convert.ToBase64String(bytes);
bytes = Convert.FromBase64String(base64);
Base64 также будет значительно короче.
Если вам нужно использовать этот формат, это явно не поможет.
Ответ 4
byte[] data = Array.ConvertAll<string, byte>(str.Split('-'), s => Convert.ToByte(s, 16));
Ответ 5
Я верю, что следующее решит это решительно.
public static byte[] HexStringToBytes(string s)
{
const string HEX_CHARS = "0123456789ABCDEF";
if (s.Length == 0)
return new byte[0];
if ((s.Length + 1) % 3 != 0)
throw new FormatException();
byte[] bytes = new byte[(s.Length + 1) / 3];
int state = 0; // 0 = expect first digit, 1 = expect second digit, 2 = expect hyphen
int currentByte = 0;
int x;
int value = 0;
foreach (char c in s)
{
switch (state)
{
case 0:
x = HEX_CHARS.IndexOf(Char.ToUpperInvariant(c));
if (x == -1)
throw new FormatException();
value = x << 4;
state = 1;
break;
case 1:
x = HEX_CHARS.IndexOf(Char.ToUpperInvariant(c));
if (x == -1)
throw new FormatException();
bytes[currentByte++] = (byte)(value + x);
state = 2;
break;
case 2:
if (c != '-')
throw new FormatException();
state = 0;
break;
}
}
return bytes;
}
Ответ 6
кажется неприятным обходным путем, чтобы разбить строку на массив строк и затем преобразовать каждую из них.
Я не думаю, что есть другой способ... формат, созданный BitConverter.ToString довольно специфичен, поэтому, если нет существующего метода для его анализа до байта [], я думаю, вы должны сделать это самостоятельно
Ответ 7
метод ToString на самом деле не предназначен для преобразования, а для обеспечения удобочитаемого формата для отладки, простой распечатки и т.д.
Я бы пересмотрел требование байта [] - String - byte [] и, вероятно, предпочел решение SLaks Base64