C# 表示字节值>;127英寸.Net字符串
我正在用字符串在.Net中编写一些二进制协议消息,除了一个特殊情况外,它基本上都是有效的 我试图发送的消息是:C# 表示字节值>;127英寸.Net字符串,c#,.net,string,character-encoding,C#,.net,String,Character Encoding,我正在用字符串在.Net中编写一些二进制协议消息,除了一个特殊情况外,它基本上都是有效的 我试图发送的消息是: String cmdPacket = "\xFD\x0B\x16MBEPEXE1."; myDevice.Write(Encoding.ASCII.GetBytes(cmdPacket)); (为了帮助解码,这些字节是253、11、22,然后是ASCII字符:“MBEPEXE1.”) 除了执行Encoding.ASCII.GetBytes外,0xFD显示为byte0x3F (值2
String cmdPacket = "\xFD\x0B\x16MBEPEXE1.";
myDevice.Write(Encoding.ASCII.GetBytes(cmdPacket));
(为了帮助解码,这些字节是253、11、22,然后是ASCII字符:“MBEPEXE1.”
)
除了执行Encoding.ASCII.GetBytes
外,0xFD
显示为byte0x3F
(值253更改为63)
(我应该指出,\x0B
和\x16
被正确解释为十六进制0B
和十六进制
)
我还尝试了编码.UTF8
和编码.UTF7
,但都没有成功
我觉得可能有一种简单的方法可以用字符串表示128以上的值,并将它们转换为字节,但我没有找到
有什么指导吗?使用LINQ,您可以执行以下操作:
String cmdPacket = "\xFD\x0B\x16MBEPEXE1.";
myDevice.Write(cmdPacket.Select(Convert.ToByte).ToArray());
String cmdPacket = "\xFD\x0B\x16MBEPEXE1.";
byte[] buffer = cmdPacket.Select(c=>(byte)c).ToArray() ;
myDevice.Write(buffer);
编辑:添加了解释
首先,您认识到字符串实际上只是一个字符数组。您需要的是一个“等效”字节数组,其中每个字节对应一个字符
要获取数组,必须将原始数组的每个字符“映射”为新数组中的一个字节。为此,可以使用内置的System.Convert.ToByte(char)
方法
一旦描述了从字符到字节的映射,就可以通过映射将输入字符串投影到数组中
希望有帮助 忽略您所做的是好是坏,编码
ISO-8859-1
将其所有字符映射到Unicode中具有相同代码的字符
// Bytes with all the possible values 0-255
var bytes = Enumerable.Range(0, 256).Select(p => (byte)p).ToArray();
// String containing the values
var all1bytechars = new string(bytes.Select(p => (char)p).ToArray());
// Sanity check
Debug.Assert(all1bytechars.Length == 256);
// The encoder, you could make it static readonly
var enc = Encoding.GetEncoding("ISO-8859-1"); // It is the codepage 28591
// string-to-bytes
var bytes2 = enc.GetBytes(all1bytechars);
// bytes-to-string
var all1bytechars2 = enc.GetString(bytes);
// check string-to-bytes
Debug.Assert(bytes.SequenceEqual(bytes2));
// check bytes-to-string
Debug.Assert(all1bytechars.SequenceEqual(all1bytechars2));
从:
ISO-8859-1被合并为ISO/IEC 10646和Unicode的前256个代码点
或者一种简单而快速的方法,将字符串
转换为字节[]
(未选中和已选中
变体)
publicstaticbyte[]StringToBytes(stringstr)
{
var bytes=新字节[str.Length];
对于(int i=0;i
我使用Windows-1252,因为它似乎给字节带来了最大的冲击
并且与所有.NET字符串值兼容
您可能希望注释掉ToLower
这是为了与SQL字符(单字节)兼容而构建的
名称空间字符串1字节
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
String8bit s1=新的String8bit(“cat”);
String8bit s2=新的String8bit(“cat”);
String8bit s3=新的String8bit(“\xFD\x0B\x16MBEPEXE1”);
HashSet hs=新的HashSet();
hs.加入(s1);
加上(s2);
加上(s3);;
System.Diagnostics.Debug.WriteLine(hs.Count.ToString());
System.Diagnostics.Debug.WriteLine(s1.Value+“”+s1.GetHashCode().ToString());
System.Diagnostics.Debug.WriteLine(s2.Value+“”+s2.GetHashCode().ToString());
System.Diagnostics.Debug.WriteLine(s3.Value+“”+s3.GetHashCode().ToString());
System.Diagnostics.Debug.WriteLine(s1.Equals(s2.ToString());
System.Diagnostics.Debug.WriteLine(s1.Equals(s3.ToString());
System.Diagnostics.Debug.WriteLine(s1.MatchStart(“ca”).ToString());
System.Diagnostics.Debug.WriteLine(s3.MatchStart(“ca”).ToString());
}
}
公共结构String8bit
{
私有静态编码EncodingUnicode=Encoding.Unicode;
私有静态编码EncodingWin1252=System.Text.Encoding.GetEncoding(“Windows-1252”);
专用字节[]字节;
公共覆盖布尔等于(对象对象对象)
{
//检查空值并比较运行时类型。
if(obj==null)返回false;
如果(!(obj为String8bit))返回false;
String8bit组件=(String8bit)对象;
如果(comp.Bytes.Length!=this.Bytes.Length)返回false;
对于(Int32 i=0;inamespace String1byte
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
String8bit s1 = new String8bit("cat");
String8bit s2 = new String8bit("cat");
String8bit s3 = new String8bit("\xFD\x0B\x16MBEPEXE1.");
HashSet<String8bit> hs = new HashSet<String8bit>();
hs.Add(s1);
hs.Add(s2);
hs.Add(s3);
System.Diagnostics.Debug.WriteLine(hs.Count.ToString());
System.Diagnostics.Debug.WriteLine(s1.Value + " " + s1.GetHashCode().ToString());
System.Diagnostics.Debug.WriteLine(s2.Value + " " + s2.GetHashCode().ToString());
System.Diagnostics.Debug.WriteLine(s3.Value + " " + s3.GetHashCode().ToString());
System.Diagnostics.Debug.WriteLine(s1.Equals(s2).ToString());
System.Diagnostics.Debug.WriteLine(s1.Equals(s3).ToString());
System.Diagnostics.Debug.WriteLine(s1.MatchStart("ca").ToString());
System.Diagnostics.Debug.WriteLine(s3.MatchStart("ca").ToString());
}
}
public struct String8bit
{
private static Encoding EncodingUnicode = Encoding.Unicode;
private static Encoding EncodingWin1252 = System.Text.Encoding.GetEncoding("Windows-1252");
private byte[] bytes;
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null) return false;
if (!(obj is String8bit)) return false;
String8bit comp = (String8bit)obj;
if (comp.Bytes.Length != this.Bytes.Length) return false;
for (Int32 i = 0; i < comp.Bytes.Length; i++)
{
if (comp.Bytes[i] != this.Bytes[i])
return false;
}
return true;
}
public override int GetHashCode()
{
UInt32 hash = (UInt32)(Bytes[0]);
for (Int32 i = 1; i < Bytes.Length; i++) hash = hash ^ (UInt32)(Bytes[0] << (i%4)*8);
return (Int32)hash;
}
public bool MatchStart(string start)
{
if (string.IsNullOrEmpty(start)) return false;
if (start.Length > this.Length) return false;
start = start.ToLowerInvariant(); // SQL is case insensitive
// Convert the string into a byte array
byte[] unicodeBytes = EncodingUnicode.GetBytes(start);
// Perform the conversion from one encoding to the other
byte[] win1252Bytes = Encoding.Convert(EncodingUnicode, EncodingWin1252, unicodeBytes);
for (Int32 i = 0; i < win1252Bytes.Length; i++) if (Bytes[i] != win1252Bytes[i]) return false;
return true;
}
public byte[] Bytes { get { return bytes; } }
public String Value { get { return EncodingWin1252.GetString(Bytes); } }
public Int32 Length { get { return Bytes.Count(); } }
public String8bit(string word)
{
word = word.ToLowerInvariant(); // SQL is case insensitive
// Convert the string into a byte array
byte[] unicodeBytes = EncodingUnicode.GetBytes(word);
// Perform the conversion from one encoding to the other
bytes = Encoding.Convert(EncodingUnicode, EncodingWin1252, unicodeBytes);
}
public String8bit(Byte[] win1252bytes)
{ // if reading from SQL char then read as System.Data.SqlTypes.SqlBytes
bytes = win1252bytes;
}
}
}
String cmdPacket = "\xFD\x0B\x16MBEPEXE1.";
byte[] buffer = cmdPacket.Select(c=>(byte)c).ToArray() ;
myDevice.Write(buffer);
// \xFD \x0B \x16 M B E P E X E 1 .
[ 0xFD , 0x0B , 0x16 , 0x4d , 0x42 , 0x45, 0x50 , 0x45 , 0x58 , 0x45 , 0x31 , 0x2E ]