需求是这样有十六进制字符串要存为byte数组
如string st = "0A000000",转为byte后为 byte[0]=10,byte[1]=0,byte[2]=0,byte[3]=0
因.net2.0可用Convert将十六进制字符串转为byte有现成的就用吧。代码如下:
public
static
byte
[] writebytes1(
string
sBytes)
... {
Stopwatch watch = new Stopwatch();
watch.Reset();
watch.Start();
Debug.Assert(sBytes.Length % 2 == 0, "数组长度错");
int pos = 0;
int len = (sBytes.Length / 2);
byte[] b = new byte[len];
int count = sBytes.Length;
for (int i = 0; i < count; i += 2)
...{
b[pos] = Convert.ToByte(sBytes.Substring(i, 2), 16);
pos++;
}
watch.Stop();
Console.WriteLine("{0}:{1}", "writebytes1", watch.Elapsed);
return b;
}
... {
Stopwatch watch = new Stopwatch();
watch.Reset();
watch.Start();
Debug.Assert(sBytes.Length % 2 == 0, "数组长度错");
int pos = 0;
int len = (sBytes.Length / 2);
byte[] b = new byte[len];
int count = sBytes.Length;
for (int i = 0; i < count; i += 2)
...{
b[pos] = Convert.ToByte(sBytes.Substring(i, 2), 16);
pos++;
}
watch.Stop();
Console.WriteLine("{0}:{1}", "writebytes1", watch.Elapsed);
return b;
}
但我觉得不够快,且发现我传的字符串长度都是8的整数倍,于是就用Convert.ToInt32以8位长度来转成uint32的数字再用BitConverter转为byte数组,但转换后数组内容与我的要求内容位置相返,所以再用Array.Reverse(Array)方法将数组返转,改了代码如下:
public
static
byte
[] writebytes2(
string
sBytes)
... {
Stopwatch watch = new Stopwatch();
watch.Reset();
watch.Start();
Debug.Assert(sBytes.Length % 2 == 0, "数组长度错");
Debug.Assert(sBytes.Length % 8 == 0, "数组长度不适合用于此方法");
int pos = 0;
int len = (sBytes.Length / 2);
byte[] b = new byte[len];
int count = sBytes.Length;
byte[] bt;
for (int i = 0; i < count; i += 8)
...{
bt = BitConverter.GetBytes(Convert.ToInt32(sBytes.Substring(i, 8), 16));
Array.Reverse(bt);
bt.CopyTo(b, pos);
pos += 4;
}
watch.Stop();
Console.WriteLine("{0}:{1}", "writebytes2", watch.Elapsed);
return b;
}
... {
Stopwatch watch = new Stopwatch();
watch.Reset();
watch.Start();
Debug.Assert(sBytes.Length % 2 == 0, "数组长度错");
Debug.Assert(sBytes.Length % 8 == 0, "数组长度不适合用于此方法");
int pos = 0;
int len = (sBytes.Length / 2);
byte[] b = new byte[len];
int count = sBytes.Length;
byte[] bt;
for (int i = 0; i < count; i += 8)
...{
bt = BitConverter.GetBytes(Convert.ToInt32(sBytes.Substring(i, 8), 16));
Array.Reverse(bt);
bt.CopyTo(b, pos);
pos += 4;
}
watch.Stop();
Console.WriteLine("{0}:{1}", "writebytes2", watch.Elapsed);
return b;
}
测了一下没快多少,而且字符串加长后反而更慢,马上用Reflector看了一下发现是Array.Reverse的实现方法把速度拖下来了,没办法只能自已写整型转byte的方法不用BitConverter和Array.Reverse。代码如下:
public
static
byte
[] writebytes3(
string
sBytes)
... {
Stopwatch watch = new Stopwatch();
watch.Reset();
watch.Start();
Debug.Assert(sBytes.Length % 2 == 0, "数组长度错");
Debug.Assert(sBytes.Length % 8 == 0, "数组长度不适合用于此方法");
int pos = 0;
int len = (sBytes.Length / 2);
byte[] b = new byte[len];
int count = sBytes.Length;
for (int i = 0; i < count; i += 8)
...{
ulong ui = Convert.ToUInt32(sBytes.Substring(i, 8), 16);
b[pos] = (byte)((ui & 0xFF000000) >> 24);
b[pos + 1] = (byte)((ui & 0x00FF0000) >> 16);
b[pos + 2] = (byte)((ui & 0x0000FF00) >> 8);
b[pos + 3] = (byte)((ui & 0x000000FF));
pos += 4;
}
watch.Stop();
Console.WriteLine("{0}:{1}", "writebytes3", watch.Elapsed);
return b;
}
... {
Stopwatch watch = new Stopwatch();
watch.Reset();
watch.Start();
Debug.Assert(sBytes.Length % 2 == 0, "数组长度错");
Debug.Assert(sBytes.Length % 8 == 0, "数组长度不适合用于此方法");
int pos = 0;
int len = (sBytes.Length / 2);
byte[] b = new byte[len];
int count = sBytes.Length;
for (int i = 0; i < count; i += 8)
...{
ulong ui = Convert.ToUInt32(sBytes.Substring(i, 8), 16);
b[pos] = (byte)((ui & 0xFF000000) >> 24);
b[pos + 1] = (byte)((ui & 0x00FF0000) >> 16);
b[pos + 2] = (byte)((ui & 0x0000FF00) >> 8);
b[pos + 3] = (byte)((ui & 0x000000FF));
pos += 4;
}
watch.Stop();
Console.WriteLine("{0}:{1}", "writebytes3", watch.Elapsed);
return b;
}
测试了一下第三种方法只用了前两种大约1/3的时间。(奇怪的是后来我又用ToUInt64取64位来写同样的方法,却反而比用ToUInt32实现的方法慢,可惜无法了解底层API是如何实现Convert.ToUInt64,还请了解的能给我说说)
static
void
Main(
string
[] args)
{
string st = " 1E041800050013000022A322232C2323303B5C2D22A322232C232330 "
+ " 1E041D00060018000022A322232C2323303B5B5265645D5C2D22A322232C232330 "
+ " 1E041E00070019000022A322232C2323302E30303B5C2D22A322232C2323302E3030 "
+ " 1E04230008001E000022A322232C2323302E30303B5B5265645D5C2D22A322232C2323302E3030 "
+ " 1E0435002A003000005F2D22A3222A20232C2323305F2D3B5C2D22A3222A20232C2323305F2D3B5F2D22A3222A20222D225F2D3B5F2D405F2D "
+ " 1E042C0029002700005F2D2A20232C2323305F2D3B5C2D2A20232C2323305F2D3B5F2D2A20222D225F2D3B5F2D405F2D " + " 1E043D002C003800005F2D22A3222A20232C2323302E30305F2D3B5C2D22A3222A20232C2323302E30305F2D3B5F2D22A3222A20222D223F3F5F2D3B5F2D405F2D "
+ " 1E0434002B002F00005F2D2A20232C2323302E30305F2D3B5C2D2A20232C2323302E30305F2D3B5F2D2A20222D223F3F5F2D3B5F2D405F2D " ;
byte [] bt1 = writebytes1(st);
byte [] bt2 = writebytes2(st);
byte [] bt3 = writebytes3(st);
for ( int i = 0 ; i < bt1.Length; i ++ )
{
if (bt1[i] != bt2[i] || bt1[i] != bt3[i] )
{
Console.WriteLine( " err " );
return ;
}
}
Console.WriteLine( " ok " );
}
{
string st = " 1E041800050013000022A322232C2323303B5C2D22A322232C232330 "
+ " 1E041D00060018000022A322232C2323303B5B5265645D5C2D22A322232C232330 "
+ " 1E041E00070019000022A322232C2323302E30303B5C2D22A322232C2323302E3030 "
+ " 1E04230008001E000022A322232C2323302E30303B5B5265645D5C2D22A322232C2323302E3030 "
+ " 1E0435002A003000005F2D22A3222A20232C2323305F2D3B5C2D22A3222A20232C2323305F2D3B5F2D22A3222A20222D225F2D3B5F2D405F2D "
+ " 1E042C0029002700005F2D2A20232C2323305F2D3B5C2D2A20232C2323305F2D3B5F2D2A20222D225F2D3B5F2D405F2D " + " 1E043D002C003800005F2D22A3222A20232C2323302E30305F2D3B5C2D22A3222A20232C2323302E30305F2D3B5F2D22A3222A20222D223F3F5F2D3B5F2D405F2D "
+ " 1E0434002B002F00005F2D2A20232C2323302E30305F2D3B5C2D2A20232C2323302E30305F2D3B5F2D2A20222D223F3F5F2D3B5F2D405F2D " ;
byte [] bt1 = writebytes1(st);
byte [] bt2 = writebytes2(st);
byte [] bt3 = writebytes3(st);
for ( int i = 0 ; i < bt1.Length; i ++ )
{
if (bt1[i] != bt2[i] || bt1[i] != bt3[i] )
{
Console.WriteLine( " err " );
return ;
}
}
Console.WriteLine( " ok " );
}