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