C# 将控制字符转换为字符串的字节数组
因此,我找到了一些示例,但没有一个完全符合我的要求(尽管很接近) 我要找的例子C# 将控制字符转换为字符串的字节数组,c#,C#,因此,我找到了一些示例,但没有一个完全符合我的要求(尽管很接近) 我要找的例子 byte[] array = { 0x02, 0x64, 0x40, 0x40, 0x03 }; string text = SomeMagicalMethod(array); //displays <STX>FOO<ETX> 编辑 使用NUnit,我针对这些测试运行了应答代码。最后一个具有一个超出0x7F范围的值。虽然将在其中使用的代码不应包含该代码,但最好是安全的,然后再抱歉 [Test
byte[] array = { 0x02, 0x64, 0x40, 0x40, 0x03 };
string text = SomeMagicalMethod(array);
//displays <STX>FOO<ETX>
编辑
使用NUnit,我针对这些测试运行了应答代码。最后一个具有一个超出0x7F范围的值。虽然将在其中使用的代码不应包含该代码,但最好是安全的,然后再抱歉
[TestFixture]
public class StringExtensionsTest
{
[Test]
public void SingleByteControlCharacterTest()
{
AssertSingleByte(0x00, "<NUL>"); AssertSingleByte(0x01, "<SOH>");
AssertSingleByte(0x02, "<STX>"); AssertSingleByte(0x03, "<ETX>");
AssertSingleByte(0x04, "<EOT>"); AssertSingleByte(0x05, "<ENQ>");
AssertSingleByte(0x06, "<ACK>"); AssertSingleByte(0x07, "<BEL>");
AssertSingleByte(0x08, "<BS>" ); AssertSingleByte(0x09, "<HT>" );
AssertSingleByte(0x0A, "<LF>" ); AssertSingleByte(0x0B, "<VT>" );
AssertSingleByte(0x0C, "<FF>" ); AssertSingleByte(0x0D, "<CR>" );
AssertSingleByte(0x0E, "<SO>" ); AssertSingleByte(0x0F, "<SI>" );
AssertSingleByte(0x10, "<DLE>"); AssertSingleByte(0x11, "<DC1>");
AssertSingleByte(0x12, "<DC2>"); AssertSingleByte(0x13, "<DC3>");
AssertSingleByte(0x14, "<DC4>"); AssertSingleByte(0x15, "<NAK>");
AssertSingleByte(0x16, "<SYN>"); AssertSingleByte(0x17, "<ETB>");
AssertSingleByte(0x18, "<CAN>"); AssertSingleByte(0x19, "<EM>" );
AssertSingleByte(0x1A, "<SUB>"); AssertSingleByte(0x1B, "<ESC>");
AssertSingleByte(0x1C, "<FS>" ); AssertSingleByte(0x1D, "<GS>" );
AssertSingleByte(0x1E, "<RS>" ); AssertSingleByte(0x1F, "<US>" );
AssertSingleByte(0x7F, "<DEL>");
}
private void AssertSingleByte(byte value, string expected)
{
byte[] array = new byte[]{value};
var actual = array.asciiOctets2String();
Assert.AreEqual(expected, actual, "Didn't print the epxected result");
}
[Test]
public void SingleCharacterTest()
{
for (byte i = 0x20; i < 0x7F; i++)
{
AssertSingleByte(i, char.ToString((char)i));
}
}
[Test]
public void SimpleTestTogether()
{
byte[] array = {0x02, 0x46,0x4F, 0x4F, 0x03};
string expected = "<STX>FOO<ETX>";
string actual = array.asciiOctets2String();
Assert.AreEqual(expected, actual, "Simple test failed");
}
[Test]
public void BigTest()
{
byte[] array = {
0x00, 0x7F, 0x03, 0x52, 0x00, 0x00, 0x2F, 0x5F, 0x20, 0x0F, 0x43, 0x41, 0x52, 0x44, 0x48, 0x4F,
0x4C, 0x44, 0x45, 0x52, 0x2F, 0x56, 0x49, 0x53, 0x41, 0x9F, 0x1F, 0x07, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30};
string expected = "<NUL><DEL><ETX>R<NUL><NUL>/_ <SI>CARDHOLDER/VISA?<US><BEL>0000000";
string actual = array.asciiOctets2String();
Assert.AreEqual(expected, actual, "BigTest Failed");
}
}
[TestFixture]
公共类StringExtensionsTest
{
[测试]
public void SingleByteControlCharacterTest()
{
AssertSingleByte(0x00,“”);AssertSingleByte(0x01,“”);
AssertSingleByte(0x02,“”);AssertSingleByte(0x03,“”);
AssertSingleByte(0x04,“”);AssertSingleByte(0x05,“”);
AssertSingleByte(0x06,“”);AssertSingleByte(0x07,“”);
AssertSingleByte(0x08,“”);AssertSingleByte(0x09,“”);
AssertSingleByte(0x0A,“”);AssertSingleByte(0x0B,“”);
AssertSingleByte(0x0C,“”);AssertSingleByte(0x0D,“”);
AssertSingleByte(0x0E,“”);AssertSingleByte(0x0F,“”);
AssertSingleByte(0x10,“”);AssertSingleByte(0x11,“”);
AssertSingleByte(0x12,“”);AssertSingleByte(0x13,“”);
AssertSingleByte(0x14,“”);AssertSingleByte(0x15,“”);
AssertSingleByte(0x16,“”);AssertSingleByte(0x17,“”);
AssertSingleByte(0x18,“”);AssertSingleByte(0x19,“”);
AssertSingleByte(0x1A,“”);AssertSingleByte(0x1B,“”);
AssertSingleByte(0x1C,“”);AssertSingleByte(0x1D,“”);
AssertSingleByte(0x1E,“”);AssertSingleByte(0x1F,“”);
AssertSingleByte(0x7F,“”);
}
私有void AssertSingleByte(字节值,应为字符串)
{
字节[]数组=新字节[]{value};
var actual=array.asciiOctets2String();
AreEqual(预期的、实际的,“未打印已执行的结果”);
}
[测试]
public void SingleCharacterTest()
{
用于(字节i=0x20;i<0x7F;i++)
{
AssertSingleByte(i,char.ToString((char)i));
}
}
[测试]
public void SimpleTestTogether()
{
字节[]数组={0x02,0x46,0x4F,0x4F,0x03};
字符串应为=“FOO”;
string actual=array.asciiOctets2String();
AreEqual(预期、实际,“简单测试失败”);
}
[测试]
公共测试()
{
字节[]数组={
0x00、0x7F、0x03、0x52、0x00、0x00、0x2F、0x5F、0x20、0x0F、0x43、0x41、0x52、0x44、0x48、0x4F,
0x4C、0x44、0x45、0x52、0x2F、0x56、0x49、0x53、0x41、0x9F、0x1F、0x07、0x30、0x30、0x30、0x30、,
0x30,0x30,0x30};
字符串expected=“R/;持卡人/VISA?0000000”;
string actual=array.asciiOctets2String();
AreEqual(预期、实际,“BigTest失败”);
}
}
您必须创建一个表格,列出您想要的控制字符,例如:
Dictionary<byte, string> controlCodes = new Dictionary<byte, string>
{
{ 0x00, "<NUL>" },
{ 0x01, "<SOH>" },
{ 0x02, "<STX>" },
{ 0x03, "<ETX>" },
...
}
当然,这可以大大改善。类似这样的方式会更有效率:
string str = string.Empty;
int i = 0, j = 0;
while (i < array.Length && j > -1)
{
j = Array.FindIndex(array, i, b => controlCodes.ContainsKey(b));
if (j > -1)
{
if (j > i)
{
str += Encoding.ASCII.GetString(array, i, j - i);
}
str += controlCodes[array[j]];
i = j + 1;
}
else
{
str += Encoding.ASCII.GetString(array, i, array.Length - i);
}
}
return str;
string str=string.Empty;
int i=0,j=0;
而(i-1)
{
j=Array.FindIndex(Array,i,b=>controlCodes.ContainsKey(b));
如果(j>-1)
{
如果(j>i)
{
str+=Encoding.ASCII.GetString(数组,i,j-i);
}
str+=控制码[array[j]];
i=j+1;
}
其他的
{
str+=Encoding.ASCII.GetString(array,i,array.Length-i);
}
}
返回str;
C#ASCII转换器会丢弃7位ASCII范围(0x00–0x7F)之外的任何字符
如果代码点超出该范围,那么就没有ASCII码。使用适当的编码(如UTF-8)
如果您知道您的字节数组是ASCII(意味着它只包含代码点0x00–0x7F),那么您根本不需要转换器。像这样的事情会对你有帮助:
static string asciiOctets2String( byte[] bytes )
{
StringBuilder sb = new StringBuilder(bytes.Length);
foreach ( char c in bytes.Select( b => (char) b ) )
{
switch ( c )
{
case '\u0000' : sb.Append("<NUL>") ; break ;
case '\u0001' : sb.Append("<SOH>") ; break ;
case '\u0002' : sb.Append("<STX>") ; break ;
case '\u0003' : sb.Append("<ETX>") ; break ;
case '\u0004' : sb.Append("<EOT>") ; break ;
case '\u0005' : sb.Append("<ENQ>") ; break ;
case '\u0006' : sb.Append("<ACK>") ; break ;
case '\u0007' : sb.Append("<BEL>") ; break ;
case '\u0008' : sb.Append("<BS>" ) ; break ;
case '\u0009' : sb.Append("<HT>" ) ; break ;
case '\u000A' : sb.Append("<LF>" ) ; break ;
case '\u000B' : sb.Append("<VT>" ) ; break ;
case '\u000C' : sb.Append("<FF>" ) ; break ;
case '\u000D' : sb.Append("<CR>" ) ; break ;
case '\u000E' : sb.Append("<SO>" ) ; break ;
case '\u000F' : sb.Append("<SI>" ) ; break ;
case '\u0010' : sb.Append("<DLE>") ; break ;
case '\u0011' : sb.Append("<DC1>") ; break ;
case '\u0012' : sb.Append("<DC2>") ; break ;
case '\u0013' : sb.Append("<DC3>") ; break ;
case '\u0014' : sb.Append("<DC4>") ; break ;
case '\u0015' : sb.Append("<NAK>") ; break ;
case '\u0016' : sb.Append("<SYN>") ; break ;
case '\u0017' : sb.Append("<ETB>") ; break ;
case '\u0018' : sb.Append("<CAN>") ; break ;
case '\u0019' : sb.Append("<EM>" ) ; break ;
case '\u001A' : sb.Append("<SUB>") ; break ;
case '\u001B' : sb.Append("<ESC>") ; break ;
case '\u001C' : sb.Append("<FS>" ) ; break ;
case '\u001D' : sb.Append("<GS>" ) ; break ;
case '\u001E' : sb.Append("<RS>" ) ; break ;
case '\u001F' : sb.Append("<US>" ) ; break ;
case '\u007F' : sb.Append("<DEL>") ; break ;
default :
if ( c > '\u007F' )
{
sb.AppendFormat( @"\u{0:X4}" , (ushort)c ) ; // in ASCII, any octet in the range 0x80-0xFF doesn't have a character glyph associated with it
}
else
{
sb.Append( c ) ;
}
break ;
}
}
return sb.ToString() ;
}
静态字符串asciiOctets2String(字节[]字节)
{
StringBuilder sb=新的StringBuilder(字节.长度);
foreach(字符c以字节为单位。选择(b=>(字符)b))
{
开关(c)
{
大小写“\u0000”:sb.Append(“”);break;
大小写“\u0001”:sb.Append(“”);break;
格“\u0002”:sb.Append(“”);break;
格“\u0003”:sb.Append(“”);break;
格“\u0004”:sb.Append(“”);break;
格“\u0005”:sb.Append(“”);break;
大小写“\u0006”:sb.Append(“”);break;
格“\u0007”:sb.Append(“”);break;
格“\u0008”:sb.Append(“”);break;
大小写“\u0009”:sb.Append(“”);break;
大小写“\u000A”:sb.Append(“”);break;
大小写“\u000B”:sb.Append(“”);break;
大小写“\u000C”:sb.Append(“”);break;
大小写“\u000D”:sb.Append(“”);break;
格“\u000E”:sb.Append(“”);break;
大小写“\u000F”:sb.Append(“”);break;
格“\u0010”:sb.Append(“”);break;
格“\u0011”:sb.Append(“”);break;
格“\u0012”:sb.Append(“”);break;
格“\u0013”:sb.Append(“”);break;
格“\u0014”:sb.Append(“”);break;
格“\u0015”:sb.Append(“”);break;
格“\u0016”:sb.Append(“”);break;
格“\u0017”:sb.Append(“”);break;
格“\u0018”:sb.Append(“”);break;
格“\u0019”:sb.Append(“”);break;
格“\u001A”:sb.追加(“”);中断;
大小写“\u001B”:sb.追加(“”);break;
格“\u001C”:sb.Append(“”);break;
大小写“\u001D”:sb.追加(“”);break;
格“\u001E”:sb.Append(“”);break;
大小写“\u001F”:sb.追加(“”);break;
格“\u007F”:sb.Append(“”);break;
违约:
如果(c>'\u007F')
{
sb.AppendFormat(@“\u{0:X4}”,(ushort)c);//在ASCII中,0x80-0xFF范围内的任何八位字节都没有与其关联的字符标志符号
}
其他的
{
sb.附加(c);
}
打破
}
}
使某人返回字符串();
}
或者另一种方法,可能比交换机快,也可能比基于词典的方法快,但可读性不强:
private static string[] controlChars =
{
"<NUL>" , "<SOH>" , "<STX>" , "<ETX>" ,
"<EOT>" , "<ENQ>" , "<ACK>" , "<BEL>" ,
"<BS>" , "<HT>" , "<LF>" , "<VT>" ,
"<FF>" , "<CR>" , "<SO>" , "<SI>" ,
"<DLE>" , "<DC1>" , "<DC2>" , "<DC3>" ,
"<DC4>" , "<NAK>" , "<SYN>" , "<ETB>" ,
"<CAN>" , "<EM>" , "<SUB>" , "<ESC>" ,
"<FS>" , "<GS>" , "<RS>" , "<US>" ,
} ;
static string asciiOctets2String( byte[] bytes )
{
StringBuilder sb = new StringBuilder(bytes.Length);
foreach ( char c in bytes.Select( b => (char) b ) )
{
if ( c < '\u0020' ) { sb.Append( controlChars[c] ) ; }
else if ( c == '\u007F' ) { sb.Append( "<DEL>" ) ; }
else if ( c > '\u007F' ) { sb.AppendFormat( @"\u{0:X4}" , (ushort)c ) ; }
else /* 0x20-0x7E */ { sb.Append( c ) ; }
}
return sb.ToString() ;
}
static string asciiOctets2String( byte[] bytes )
{
StringBuilder sb = new StringBuilder(bytes.Length);
foreach ( char c in bytes.Select( b => (char) b ) )
{
switch ( c )
{
case '\u0000' : sb.Append("<NUL>") ; break ;
case '\u0001' : sb.Append("<SOH>") ; break ;
case '\u0002' : sb.Append("<STX>") ; break ;
case '\u0003' : sb.Append("<ETX>") ; break ;
case '\u0004' : sb.Append("<EOT>") ; break ;
case '\u0005' : sb.Append("<ENQ>") ; break ;
case '\u0006' : sb.Append("<ACK>") ; break ;
case '\u0007' : sb.Append("<BEL>") ; break ;
case '\u0008' : sb.Append("<BS>" ) ; break ;
case '\u0009' : sb.Append("<HT>" ) ; break ;
case '\u000A' : sb.Append("<LF>" ) ; break ;
case '\u000B' : sb.Append("<VT>" ) ; break ;
case '\u000C' : sb.Append("<FF>" ) ; break ;
case '\u000D' : sb.Append("<CR>" ) ; break ;
case '\u000E' : sb.Append("<SO>" ) ; break ;
case '\u000F' : sb.Append("<SI>" ) ; break ;
case '\u0010' : sb.Append("<DLE>") ; break ;
case '\u0011' : sb.Append("<DC1>") ; break ;
case '\u0012' : sb.Append("<DC2>") ; break ;
case '\u0013' : sb.Append("<DC3>") ; break ;
case '\u0014' : sb.Append("<DC4>") ; break ;
case '\u0015' : sb.Append("<NAK>") ; break ;
case '\u0016' : sb.Append("<SYN>") ; break ;
case '\u0017' : sb.Append("<ETB>") ; break ;
case '\u0018' : sb.Append("<CAN>") ; break ;
case '\u0019' : sb.Append("<EM>" ) ; break ;
case '\u001A' : sb.Append("<SUB>") ; break ;
case '\u001B' : sb.Append("<ESC>") ; break ;
case '\u001C' : sb.Append("<FS>" ) ; break ;
case '\u001D' : sb.Append("<GS>" ) ; break ;
case '\u001E' : sb.Append("<RS>" ) ; break ;
case '\u001F' : sb.Append("<US>" ) ; break ;
case '\u007F' : sb.Append("<DEL>") ; break ;
default :
if ( c > '\u007F' )
{
sb.AppendFormat( @"\u{0:X4}" , (ushort)c ) ; // in ASCII, any octet in the range 0x80-0xFF doesn't have a character glyph associated with it
}
else
{
sb.Append( c ) ;
}
break ;
}
}
return sb.ToString() ;
}
private static string[] controlChars =
{
"<NUL>" , "<SOH>" , "<STX>" , "<ETX>" ,
"<EOT>" , "<ENQ>" , "<ACK>" , "<BEL>" ,
"<BS>" , "<HT>" , "<LF>" , "<VT>" ,
"<FF>" , "<CR>" , "<SO>" , "<SI>" ,
"<DLE>" , "<DC1>" , "<DC2>" , "<DC3>" ,
"<DC4>" , "<NAK>" , "<SYN>" , "<ETB>" ,
"<CAN>" , "<EM>" , "<SUB>" , "<ESC>" ,
"<FS>" , "<GS>" , "<RS>" , "<US>" ,
} ;
static string asciiOctets2String( byte[] bytes )
{
StringBuilder sb = new StringBuilder(bytes.Length);
foreach ( char c in bytes.Select( b => (char) b ) )
{
if ( c < '\u0020' ) { sb.Append( controlChars[c] ) ; }
else if ( c == '\u007F' ) { sb.Append( "<DEL>" ) ; }
else if ( c > '\u007F' ) { sb.AppendFormat( @"\u{0:X4}" , (ushort)c ) ; }
else /* 0x20-0x7E */ { sb.Append( c ) ; }
}
return sb.ToString() ;
}