C# BitConverter.ToString() 反过来?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1230303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 13:58:52  来源:igfitidea点击:

BitConverter.ToString() in reverse?

c#.net

提问by Darren Oster

I have an array of bytes that I would like to store as a string. I can do this as follows:

我有一个字节数组,我想将其存储为字符串。我可以这样做:

byte[] array = new byte[] { 0x01, 0x02, 0x03, 0x04 };
string s = System.BitConverter.ToString(array);

// Result: s = "01-02-03-04"

So far so good. Does anyone know how I get this back to an array? There is no overload of BitConverter.GetBytes() that takes a string, and it seems like a nasty workaround to break the string into an array of strings and then convert each of them.

到现在为止还挺好。有谁知道我如何将它恢复到数组?没有接受字符串的 BitConverter.GetBytes() 的重载,将字符串分解为字符串数组然后转换每个字符串似乎是一种令人讨厌的解决方法。

The array in question may be of variable length, probably about 20 bytes.

有问题的数组可能是可变长度的,大概是 20 个字节。

采纳答案by CoderTao

Not a built in method, but an implementation. (It could be done without the split though).

不是内置方法,而是实现。(尽管可以在没有拆分的情况下完成)。

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);

Method without Split: (Makes many assumptions about string format)

没有拆分的方法:(对字符串格式做了很多假设)

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);

And one more method, without either split or substrings. You may get shot if you commit this to source control though. I take no responsibility for such health problems.

还有一种方法,没有拆分或子字符串。但是,如果您将其提交给源代码管理,您可能会被枪杀。我对此类健康问题不承担任何责任。

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);
}

(basically implementing base16 conversion on two chars)

(基本上在两个字符上实现 base16 转换)

回答by Thomas Levesque

it seems like a nasty workaround to break the string into an array of strings and then convert each of them.

将字符串分解为字符串数组然后转换每个字符串似乎是一种令人讨厌的解决方法。

I don't think there's another way... the format produced by BitConverter.ToString is quite specific, so if there is no existing method to parse it back to a byte[], I guess you have to do it yourself

我觉得没有别的办法了。。。BitConverter.ToString生成的格式是很具体的,所以如果没有现成的方法解析回byte[]的话,估计得自己动手了

回答by Guffa

You can parse the string yourself:

您可以自己解析字符串:

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])
   );
}

The neatest solution though, I believe, is using extensions:

不过,我相信最简洁的解决方案是使用扩展:

byte[] data = s.Split('-').Select(b => Convert.ToByte(b, 16)).ToArray();

回答by Jason Kresowaty

I believe the following will solve this robustly.

我相信以下内容将有力地解决这个问题。

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;
}

回答by SLaks

If you don't need that specific format, try using Base64, like this:

如果您不需要该特定格式,请尝试使用Base64,如下所示:

var bytes = new byte[] { 0x12, 0x34, 0x56 };
var base64 = Convert.ToBase64String(bytes);
bytes = Convert.FromBase64String(base64);

Base64 will also be substantially shorter.

Base64 也将大大缩短。

If you need to use that format, this obviously won't help.

如果您需要使用该格式,这显然无济于事。

回答by DataFiddler

the ToString method is not really intended as a conversion, rather to provide a human-readable format for debugging, easy printout, etc.
I'd rethink about the byte[] - String - byte[] requirement and probably prefer SLaks' Base64 solution

ToString 方法并不是真正打算作为转换,而是为调试、轻松打印输出等提供人类可读的格式。
我会重新考虑 byte[] - String - byte[] 要求,并且可能更喜欢 SLaks 的 Base64 解决方案

回答by vido

byte[] data = Array.ConvertAll<string, byte>(str.Split('-'), s => Convert.ToByte(s, 16));