BitConverter.ToString() in reverse?
本问题已经有最佳答案,请猛点这里访问。
我有一个字节数组,希望将其存储为字符串。我可以这样做:
1 2 3 4 | byte[] array = new byte[] { 0x01, 0x02, 0x03, 0x04 }; string s = System.BitConverter.ToString(array); // Result: s ="01-02-03-04" |
到现在为止,一直都还不错。有人知道我是怎么把这个放回阵列的吗?不存在需要字符串的bitconverter.getBytes()重载,将字符串分解为一个字符串数组,然后对每个字符串进行转换似乎是一个棘手的解决方案。
所讨论的数组可能是可变长度的,可能大约20个字节。
您可以自己分析字符串:
1 2 3 4 5 6 7 | 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]) ); } |
不过,我认为最新的解决方案是使用扩展:
1 | byte[] data = s.Split('-').Select(b => Convert.ToByte(b, 16)).ToArray(); |
不是内置方法,而是实现。(不过,这可以在没有分裂的情况下完成)。
1 2 3 | 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); |
无拆分方法:(对字符串格式做了许多假设)
1 2 3 4 | 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); |
还有一个方法,没有拆分或子字符串。但是,如果将此提交到源代码管理,则可能会被枪击。我对这种健康问题不负责任。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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转换)
如果不需要特定格式,请尝试使用base64,如下所示:
1 2 3 | var bytes = new byte[] { 0x12, 0x34, 0x56 }; var base64 = Convert.ToBase64String(bytes); bytes = Convert.FromBase64String(base64); |
base64也将大大缩短。
如果您需要使用这种格式,这显然没有帮助。
1 | byte[] data = Array.ConvertAll<string, byte>(str.Split('-'), s => Convert.ToByte(s, 16)); |
我相信下面将有力地解决这个问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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; } |
ToString方法并不是真正的转换,而是为调试、轻松打印等提供一种人类可读的格式。
我会重新考虑byte[]-string-byte[]的要求,可能更喜欢slaks的base64解决方案。
it seems like a nasty workaround to break the string into an array of strings and then convert each of them.
我觉得没有别的办法…bitconverter.toString生成的格式非常具体,因此如果没有现有的方法将其解析回byte[],我想您必须自己做。