您的位置:首页 > 其它

将十六进制字符串转为byte数组

2007-11-08 14:30 477 查看
需求是这样有十六进制字符串要存为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;


}

但我觉得不够快,且发现我传的字符串长度都是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;


}

测了一下没快多少,而且字符串加长后反而更慢,马上用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;


}

测试了一下第三种方法只用了前两种大约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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: