Jas*_*ley 9 c# optimization character-encoding
是否可以将此代码简化为更清晰/更快的形式?
StringBuilder builder = new StringBuilder();
var encoding = Encoding.GetEncoding(936);
// convert the text into a byte array
byte[] source = Encoding.Unicode.GetBytes(text);
// convert that byte array to the new codepage.
byte[] converted = Encoding.Convert(Encoding.Unicode, encoding, source);
// take multi-byte characters and encode them as separate ascii characters
foreach (byte b in converted)
builder.Append((char)b);
// return the result
string result = builder.ToString();
Run Code Online (Sandbox Code Playgroud)
简单地说,它需要一个带有中文字符的字符串,如郓,并将它们转换为ài.
例如,十进制中的中文字符为十六进制的37126或0x9106.
请参见http://unicodelookup.com/#0x9106/1
转换为字节数组,得到[145,6](145*256 + 6 = 37126).当在CodePage 936(简体中文)中编码时,我们得到[224,105].如果我们将这个字节数组分解为单个字符,我们224 = e0 =à和105 = 69 = i在unicode中.
请参见http://unicodelookup.com/#0x00e0/1 和 http://unicodelookup.com/#0x0069/1
因此,我们正在进行编码转换,并确保输出Unicode字符串中的所有字符都可以使用最多两个字节来表示.
更新:我需要此最终表示,因为这是我的收据打印机接受的格式.让我永远想通了!:)由于我不是编码专家,我正在寻找更简单或更快的代码,但输出必须保持不变.
更新(清洁版):
return Encoding.GetEncoding("ISO-8859-1").GetString(Encoding.GetEncoding(936).GetBytes(text));
Run Code Online (Sandbox Code Playgroud)
Eam*_*nne 10
好吧,对于一个,你不需要在调用之前将"内置"字符串表示转换为字节数组Encoding.Convert.
你可以这样做:
byte[] converted = Encoding.GetEncoding(936).GetBytes(text);
Run Code Online (Sandbox Code Playgroud)
然后从该字节数组重建一个字符串,其中char值直接映射到字节,你可以做...
static string MangleTextForReceiptPrinter(string text) {
return new string(
Encoding.GetEncoding(936)
.GetBytes(text)
.Select(b => (char) b)
.ToArray());
}
Run Code Online (Sandbox Code Playgroud)
我不会太担心效率; 你打算在收据打印机上打印多少MB /秒?
Joe指出,有一种编码可以直接将字节值0-255映射到代码点,而且它是古老的Latin1,它允许我们将函数缩短为......
return Encoding.GetEncoding("Latin1").GetString(
Encoding.GetEncoding(936).GetBytes(text)
);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果这是一个有缺陷的Windows专用API(它的外观),你可能正在处理代码页1252(几乎完全相同).您可以尝试使用反射器来查看它在通过线路发送之前对System.String执行的操作.
几乎所有东西都比这更干净 - 你真的在这里滥用文字,IMO.您试图将有效的不透明二进制数据(编码文本)表示为文本数据...因此您可能会获得诸如铃声字符,转义等内容.
在文本中编码不透明二进制数据的常规方法是base64,因此您可以使用:
return Convert.ToBase64String(Encoding.GetEncoding(936).GetBytes(text));
Run Code Online (Sandbox Code Playgroud)
生成的文本将完全是ASCII,这不太可能导致您麻烦.
编辑:如果您需要该输出,我强烈建议您将其表示为字节数组而不是字符串...从那时起将其作为字节数组传递,因此您不必尝试执行字符串操作在上面.