Most light weight conversion from hex to byte in c#?
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
How do you convert Byte Array to Hexadecimal String, and vice versa?
我需要一个高效和快速的方法来完成这个转换。我试过两种不同的方法,但它们对我来说不够有效。对于具有大量数据的应用程序,是否有其他快速方法可以实时完成此任务?
1 2 3 4 | public byte[] StringToByteArray(string hex) { return Enumerable.Range(0, hex.Length / 2).Select(x => Byte.Parse(hex.Substring(2 * x, 2), NumberStyles.HexNumber)).ToArray(); } |
上面的那个对我来说更有效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public static byte[] stringTobyte(string hexString) { try { int bytesCount = (hexString.Length) / 2; byte[] bytes = new byte[bytesCount]; for (int x = 0; x < bytesCount; ++x) { bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16); } return bytes; } catch { throw; } |
如果你真的需要效率,那么:
- 不创建子字符串
- 不创建迭代器
或者,去掉只有一个返回的
这将是一个非常有效的版本:
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 | public static byte[] ParseHex(string hexString) { if ((hexString.Length & 1) != 0) { throw new ArgumentException("Input must have even number of characters"); } int length = hexString.Length / 2; byte[] ret = new byte[length]; for (int i = 0, j = 0; i < length; i++) { int high = ParseNybble(hexString[j++]); int low = ParseNybble(hexString[j++]); ret[i] = (byte) ((high << 4) | low); } return ret; } private static int ParseNybble(char c) { // TODO: Benchmark using if statements instead switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return c - '0'; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': return c - ('a' - 10); case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': return c - ('A' - 10); default: throw new ArgumentException("Invalid nybble:" + c); } return c; } |
托多指的是这样的一种选择。我没有测量哪个更快。
1 2 3 4 5 6 7 8 9 10 11 12 13 | private static int ParseNybble(char c) { if (c >= '0' && c <= '9') { return c - '0'; } c = (char) (c & ~0x20); if (c >= 'A' && c <= 'F') { return c - ('A' - 10); } throw new ArgumentException("Invalid nybble:" + c); } |
作为Jon基于
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 | public static byte[] ParseHex(string hexString) { if ((hexString.Length & 1) != 0) { throw new ArgumentException("Input must have even number of characters"); } byte[] ret = new byte[hexString.Length / 2]; for (int i = 0; i < ret.Length; i++) { int high = ParseNybble(hexString[i*2]); int low = ParseNybble(hexString[i*2+1]); ret[i] = (byte) ((high << 4) | low); } return ret; } private static int ParseNybble(char c) { unchecked { uint i = (uint)(c - '0'); if(i < 10) return (int)i; i = ((uint)c & ~0x20u) - 'A'; if(i < 6) return (int)i+10; throw new ArgumentException("Invalid nybble:" + c); } } |
我从另一个问题中获取了基准代码,并对其进行了重新编写,以测试这里给出的十六进制到字节的方法:
1 2 3 4 | HexToBytesJon: 36979.7 average ticks (over 150 runs) HexToBytesJon2: 35886.4 average ticks (over 150 runs) HexToBytesJonCiC: 31230.2 average ticks (over 150 runs) HexToBytesJase: 15359.1 average ticks (over 150 runs) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static byte[] HexToBytesJase(string hexString) { if ((hexString.Length & 1) != 0) { throw new ArgumentException("Input must have even number of characters"); } byte[] ret = new byte[hexString.Length/2]; for (int i = 0; i < ret.Length; i++) { int high = hexString[i*2]; int low = hexString[i*2+1]; high = (high & 0xf) + ((high & 0x40) >> 6) * 9; low = (low & 0xf) + ((low & 0x40) >> 6) * 9; ret[i] = (byte)((high << 4) | low); } return ret; } |