(超难问题)byte[]数组与string怎么转换?

dyw31415926 2006-11-23 11:19:20
如题: 给一个byte[] 可以将它转成string类型(不是string数组!),然后还可以从这个string还原为原来的byte[]类型.最好高效率的!

此问题很难!!不要随便放个
byte[] byteArray = new byte[] { 0x01, 200 };
string s = System.Text.Encoding.Unicode.GetString (byteArray );
byte[] array = System.Text.Encoding.Unicode.GetBytes(s);
就敷衍我,其实是错误的,我经过了测试,发现上面的方法是错误的,在byte[]是奇数时会出错,改用Default也不行,当byte[]里有如上的像200等比较大的数时还是会出错!!!!


是高手就来挑战吧!!!!
...全文
3711 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
KissApple 2006-12-15
  • 打赏
  • 举报
回复
mark
davidwang1207 2006-12-14
  • 打赏
  • 举报
回复
占位, 学习 !~
hhhui2008 2006-12-06
  • 打赏
  • 举报
回复
学习!
Ivony 2006-11-27
  • 打赏
  • 举报
回复
这就是误导的后果……
记得以前也有个人提这个问题,我告诉他要用BASE64,他还非说我错了,应该用Unicode编码。
flowersea312 2006-11-27
  • 打赏
  • 举报
回复
Convert.ToBase64String
Convert.FromBase64String
这个好
sdl2005lyx 2006-11-27
  • 打赏
  • 举报
回复
lz,你对问题的深入研究值得大家学习啊。。。。
dyw31415926 2006-11-27
  • 打赏
  • 举报
回复
viena(维也纳nn) ( ) 信誉:100 Blog
---------------------------------------
//任意byte数组转为字符串
string str = BitConverter.ToString(byteArr);

//转回byte数组
int len = (str.Length+1)/3
byte[] byteArr2 = new byte[len]
for(int i=0;i<len;i++)
{
byteArr2[i] = Convert.ToByte(str.Substring(i*3,2),16);
}
以上把任意byte数组(0-255)二进制信息与16进制字符串互转,保证不会丢失信息
系统自带的未必是效率最高的
直接调用只是方便而以
如果用我说的Unsafe代码指针移动,直接得到无分隔16进制字符串
效率要高得多

至于/3 乘3
你看一下BitConverter.ToString的结果格式就知道了
是每字节两位16进制,以'-'隔开的
除三得到字节数
在字符串中的位置也是步长为三,比如从0,3,6位置每次取两个字符转为字节
-------------------------------------------------------------------------
谢谢
dyw31415926 2006-11-23
  • 打赏
  • 举报
回复
或者你直接对byte[]操作效率更高,除非你的string 需要显示,所以说不用string 也可以。
你先看看ASCII码表吧,你就知道了。

-----------------------------------
欢迎指点
注: byte[] 转换成的s不需要输出或显示,只需要从该s转回来的新的byte[] 与原来的byte[]数值是一样的即可
dyw31415926 2006-11-23
  • 打赏
  • 举报
回复
to:lifeixie(lifeixie) ( )
string b = Encoding.GetEncoding("gb2312").GetString(a);
byte[] y = Encoding.GetEncoding("gb2312").GetBytes(b);

----------------------------------------------
很抱歉的告诉您,你给的代码没能通过第一条标准(保证返回正确的结果),所以第二条的比较(比效率)你暂时要当观众了:)
byte[] byteArray = new byte[] { 0x01, 200, 0x02, 129, 155 };
string s;
byte[] array;
s = Encoding.GetEncoding("gb2312").GetString(byteArray );
array = Encoding.GetEncoding("gb2312").GetBytes(s);

返回的结果 array = {1,63,129,155};是不正确的
lifeixie 2006-11-23
  • 打赏
  • 举报
回复
或者你想个办法,压缩一下也可以。
//解压字符
//0x5A是Z后面是 没意思字符
//0x30 是 0
//0-Z
public string ToCode(string bbb)
{
string ret = "";

bbb+=("".PadLeft(4-(bbb.Length % 4))).Replace(" ","0");

for(int i = 0; i < bbb.Length; i += 4)
{//判断余数如果有等于为空
char temp1 = (char)(bbb[i] > 0x5A ? bbb[i] - 0x30 - 6 : bbb[i] - 0x30);
char temp2 = (char)(bbb[i+1] > 0x5A ? bbb[i+1] - 0x30 - 6 : bbb[i+1] - 0x30);
char temp3 = (char)(bbb[i+2] > 0x5A ? bbb[i+2] - 0x30 - 6 : bbb[i+2] - 0x30);
char temp4 = (char)(bbb[i+3] > 0x5A ? bbb[i+3] - 0x30 - 6 : bbb[i+3] - 0x30);
char a = (char)(temp1 & 0x0F);

if(a<0x0a)
{
a=(char)(a+0x30);
}
else
{
a=(char)(a+0x37);
}

char b = (char)(temp1>>4);
char c=(char)((temp2&0x03)<<2);
b = (char)(b +c);
if(b<0x0a)
{
b=(char)(b+0x30);
}
else
{
b=(char)(b+0x37);
}
c = (char)((temp2>>2) & 0x0f);

if(c<0x0a)
{
c=(char)(c+0x30);
}
else
{
c=(char)(c+0x37);
}
char tp = c;
ret =ret + (char)b + (char)a;

a = (char)(temp3 & 0x0F);
if(a<0x0a)
{
a=(char)(a+0x30);
}
else
{
a=(char)(a+0x37);
}
b = (char)(temp3>>4 );
c=(char)((temp4&0x03)<<2);
b = (char)(b +c);

if(b<0x0a)
{
b=(char)(b+0x30);
}
else
{
b=(char)(b+0x37);
}
c = (char)((temp4>>2) & 0x0f);

if(c<0x0a)
{
c=(char)(c+0x30);
}
else
{
c=(char)(c+0x37);
}
ret=ret + a + tp + c + b;


}
return ret;

}



这是解压缩后的

或者你直接对byte[]操作效率更高,除非你的string 需要显示,所以说不用string 也可以。
你先看看ASCII码表吧,你就知道了。
lifeixie 2006-11-23
  • 打赏
  • 举报
回复
ASCII不可以显示 127以后的数字,你那里肯定有不可显示字符!!!!!!!!!!!!
语言
C#

全部显示
获取 ASCII(7 位)字符集的编码。

[C#]
public static Encoding ASCII {get;}

属性值
ASCII(7 位)字符集的编码。

备注
ASCII 字符限于最低 128 个 Unicode 字符(从 U+0000 到 U+007f)
Ascii是127个,后来又增加到255个,后来增加的这128个叫"扩展字符集"
string b = Encoding.GetEncoding("gb2312").GetString(a);
byte[] y = Encoding.GetEncoding("gb2312").GetBytes(b);


不过,sting 的截取方面..........

liujia_0421 2006-11-23
  • 打赏
  • 举报
回复
有意思,先作个记号...
dyw31415926 2006-11-23
  • 打赏
  • 举报
回复
我对 bitpolar(日落雁行斜) ( ) 的程序进行了测试,测试结果以及代码如下:

private void button1_Click(object sender, EventArgs e)
{
byte[] byteArray = new byte[] { 0x01,200,0x02,129,155};
string s;
byte[] array;
int startTickCount, endTickCount, timeTaken;
// Call GetTickCount to get the starting tick count
startTickCount = Environment.TickCount;
for (int ii = 0; ii < 1000000; ii++)
{
s = Convert.ToBase64String(byteArray);
//array = Convert.FromBase64String(s);
}
endTickCount = Environment.TickCount;
// Calculate the time taken (in ms) to initialize the controls
timeTaken = endTickCount - startTickCount;
// Display the time taken in a message box
Console .WriteLine ("Load Time: " + timeTaken.ToString() + "ms");
}

-------------------
s = Convert.ToBase64String(byteArray);
//array = Convert.FromBase64String(s);
都执行
Load Time: 516ms
Load Time: 500ms
Load Time: 547ms
Load Time: 515ms
Load Time: 532ms
Load Time: 532ms
Load Time: 516ms
Load Time: 515ms
Load Time: 516ms
Load Time: 516ms
只执行s = Convert.ToBase64String(byteArray);
Load Time: 203ms
Load Time: 235ms
Load Time: 188ms
Load Time: 203ms
Load Time: 235ms
Load Time: 203ms
Load Time: 250ms
Load Time: 203ms
Load Time: 203ms
Load Time: 203ms


}
---------------------------------
对viena(维也纳nn) ( ) 的测试程序
private void button2_Click(object sender, EventArgs e)
{
byte[] byteArray = new byte[] { 0x01, 200, 0x02, 129, 155 };
string s;
byte[] array;
int len;
int startTickCount, endTickCount, timeTaken;
// Call GetTickCount to get the starting tick count
startTickCount = Environment.TickCount;
for (int ii = 0; ii < 1000000; ii++)
{
s = BitConverter.ToString(byteArray);
//转回byte数组
// len = (s.Length + 1) / 3;
// array = new byte[len];
// for (int i = 0; i < len; i++)
// {
// array[i] = Convert.ToByte(s.Substring(i * 3, 2), 16);
// }
}
endTickCount = Environment.TickCount;
// Calculate the time taken (in ms) to initialize the controls
timeTaken = endTickCount - startTickCount;
// Display the time taken in a message box
Console.WriteLine("Load Time: " + timeTaken.ToString() + "ms");
}
-----------------
都执行
Load Time: 1782ms
Load Time: 1750ms
Load Time: 1781ms
Load Time: 1781ms
Load Time: 1765ms
Load Time: 1813ms
Load Time: 1812ms
Load Time: 1734ms
Load Time: 1734ms
Load Time: 1719ms
Load Time: 1906ms
s = BitConverter.ToString(byteArray);
Load Time: 250ms
Load Time: 250ms
Load Time: 265ms
Load Time: 250ms
Load Time: 250ms
Load Time: 250ms
Load Time: 250ms
Load Time: 203ms
Load Time: 203ms
Load Time: 203ms

午饭后继续讨论谁的代码更厉害

viena 2006-11-23
  • 打赏
  • 举报
回复
如果要效率高,必须要用Unsafe代码,以指针来移动位置
反编译下CLR(mscorlib)就知道了,里面都是Unsafe代码
bitpolar 2006-11-23
  • 打赏
  • 举报
回复
自己写一个转换的函数 除非目的特别确定
否则难说一定就比微软的工程师封装的还好吧
sdl2005lyx 2006-11-23
  • 打赏
  • 举报
回复
lz:
我原来用str.Split将字符串分割,对上百万次的转换效率可能不高,可以换成正则表达式,效率会提高一些,你试试:
string str = "01 02 30";
//string[] stra = str.Split(new char[] {' '});
Regex q=new Regex(" ",RegexOptions.Compiled);
//RegexOptions.Compiled能够将正则表达式转换为本地机器码,以便提高性能
string[] strArr=q.Split(str);
byte[] b = new byte[strArr.Length];
//for (int i = 0; i < stra.Length; i++)
foreach(string ss in strArr)
{
//b[i] = byte.Parse(stra[i], System.Globalization.NumberStyles.HexNumber);
b[i] = Convert.ToByte(stra[i], 16);//两种都行
}

bitpolar 2006-11-23
  • 打赏
  • 举报
回复
我用了一年
Convert.ToBase64String
Convert.FromBase64String
从来没出过错 莫非咱俩的字符串不一样?
至于效率是不是最高就不知道了
viena 2006-11-23
  • 打赏
  • 举报
回复
以上把任意byte数组(0-255)二进制信息与16进制字符串互转,保证不会丢失信息
viena 2006-11-23
  • 打赏
  • 举报
回复
//任意byte数组转为字符串
string str = BitConverter.ToString(byteArr);

//转回byte数组
int len = (str.Length+1)/3
byte[] byteArr2 = new byte[len]
for(int i=0;i<len;i++)
{
byteArr2[i] = Convert.ToByte(str.Substring(i*3,2),16);
}
cancerser 2006-11-23
  • 打赏
  • 举报
回复
留个名先
加载更多回复(27)

110,588

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧