C# BitConverter.ToString()是否相反?

C# BitConverter.ToString()是否相反?,c#,.net,C#,.net,我有一个字节数组,我想存储为字符串。我可以这样做: byte[] array = new byte[] { 0x01, 0x02, 0x03, 0x04 }; string s = System.BitConverter.ToString(array); // Result: s = "01-02-03-04" 到目前为止还不错。有人知道我是如何把它带回阵列的吗?不存在接受字符串的BitConverter.GetBytes()重载,将字符串分解为字符串数组,然后对每个字符串进行转换似乎是一个

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

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

// Result: s = "01-02-03-04"
到目前为止还不错。有人知道我是如何把它带回阵列的吗?不存在接受字符串的BitConverter.GetBytes()重载,将字符串分解为字符串数组,然后对每个字符串进行转换似乎是一个棘手的解决方法


所讨论的数组可能长度可变,大约为20字节。

不是内置方法,而是实现。(不过也可以不用拆分)

String[]arr=str.Split('-');
字节[]数组=新字节[arr.Length];
对于(inti=0;i'9'),十六=(char)(十六-'A'+10);
否则十六个-='0';
字符数=s[3*i+1];
如果(一个数>'9')一个数=(字符)(一个数-'A'+10);
其他值-='0';
arr1[i]=(字节)(16*16+1);
}
(基本上在两个字符上实现base16转换)

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


我不认为还有别的办法。。。BitConverter.ToString生成的格式非常具体,因此如果没有现有的方法将其解析回字节[],我想您必须自己进行解析

您可以自己解析字符串:

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

我相信以下几点将有力地解决这个问题

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;
}
publicstaticbyte[]HexStringToBytes(字符串s)
{
常量字符串HEX_CHARS=“0123456789ABCDEF”;
如果(s.Length==0)
返回新字节[0];
如果((s.Length+1)%3!=0)
抛出新的FormatException();
字节[]字节=新字节[(s.Length+1)/3];
int state=0;//0=预期第一位数字,1=预期第二位数字,2=预期连字符
int currentByte=0;
int x;
int值=0;
foreach(字符c在s中)
{
开关(状态)
{
案例0:
x=十六进制字符索引of(字符不变量(c));
如果(x==-1)
抛出新的FormatException();

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

var bytes = new byte[] { 0x12, 0x34, 0x56 };
var base64 = Convert.ToBase64String(bytes);
bytes = Convert.FromBase64String(base64);
Base64也将大大缩短


如果您需要使用该格式,这显然是没有帮助的。

ToString方法并非真正用于转换,而是提供一种便于调试、轻松打印输出等的可读格式。
我会重新考虑byte[]-String-byte[]需求,可能更喜欢SLaks的Base64解决方案

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

是的,可能会归结到这一点。我希望我在某个地方遗漏了一种方法-不在某个地方烘焙它似乎很奇怪…“这可以在没有拆分的情况下完成”:怎么做?嗯…我认为拆分版本更整洁,可能更快(以一种非常小的方式)拆分版本的速度不是更快。拆分必须为其返回分配一个数组,如果字符串较大,则速度可能会非常慢。对于较大的字符串,循环字符串中的字符会更快。公平调用。但键入速度更快…:)您将使用拆分或编写非常具体的拆分实现…只需使用spli即可t、 你是对的,虽然我非常确定数据的格式正确(无论哪种情况都会引发异常),但我可能会选择拆分版本或Linq版本——特别是因为它可以节省大约40行代码。我对Linq解决方案投了赞成票,但对“低技术”的问题却出现了编译时错误解决方案。需要一组额外的括号,但很容易修复。
(字节)(“0123456789ABCDEF.IndexOf(s[i*3])*16+“0123456789ABCDEF.IndexOf(s[i*3+1]))
@dana:是的,你说得对,它需要另一个括号。很好的catch.Lambda/Extensions解决方案非常优雅!谢谢!我需要的答案非常好,比BitConverter.Thx好得多。现场Thx可以准确地解释这段代码的功能吗?一行代码很好,但通常会有很多事情发生,以实现结果需要。这只是CoderTao答案的简短版本。它将字节数组构造函数和“for”循环替换为“array.ConvertAll”方法。它使用lambda表达式将每个十六进制字符串转换为一个字节。我认为这是自我解释。
byte[] data = s.Split('-').Select(b => Convert.ToByte(b, 16)).ToArray();
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;
}
var bytes = new byte[] { 0x12, 0x34, 0x56 };
var base64 = Convert.ToBase64String(bytes);
bytes = Convert.FromBase64String(base64);
byte[] data = Array.ConvertAll<string, byte>(str.Split('-'), s => Convert.ToByte(s, 16));