我在尝试将包含简体中文的字符串转换为双字节编码(GB2312)时遇到问题。这是用于将中文字符打印到斑马打印机上。
我正在查看的规格显示了"冈区色呆"的文字示例。它们显示为转换为十六进制值38_54_47_78_49_2b_34_74。
在我的C#代码中,我试图使用下面的代码作为测试来转换它。我的结果似乎在前导十六进制值中偏离了7。我在这里缺少什么?
private const string SimplifiedChineseChars = "冈区色呆";
[TestMethod]
public void GetBackCorrectHexValues()
{
byte[] bytes = Encoding.GetEncoding(20936).GetBytes(SimplifiedChineseChars);
string hex = BitConverter.ToString(bytes).Replace("-", "_");
//I get the following: B8_D4_C7_F8_C9_AB_B4_F4
//I am expecting: 38_54_47_78_49_2b_34_74
}
答案 0 :(得分:3)
对我来说唯一有意义的是38_54_47_78_49_2b_34_74
是某种形式的7位编码。
有趣的是,GB2312
编码的7位版本确实存在,并称为HZ
字符编码。
这是wikipedia entry on HZ。有趣的部分:
发明
HZ
...编码是为了方便通过电子邮件使用中文字符,当时只允许 7位 字符。
HZ
代码使用 仅可打印的 , 7位 字符来表示中文字符
而且,根据this Microsoft reference page on EncodingInfo.GetEncoding,.NET支持这种字符编码:
52936 hz-gb-2312 简体中文(HZ)
如果我尝试使用代码,并将字符编码替换为HZ
,我会得到:
static void Main(string[] args)
{
const string SimplifiedChineseChars = "冈区色呆";
byte[] bytes = Encoding.GetEncoding("hz-gb-2312").GetBytes(SimplifiedChineseChars);
string hex = BitConverter.ToString(bytes).Replace("-", "_");
Console.WriteLine(hex);
}
输出:
7E_7B_的 38_54_47_78_49_2B_34_74 强> _7E_7D
因此,除了在中文字符字节之前和之后添加转义序列~{
和~}
之外,您基本上可以得到您正在寻找的内容。这些转义序列是必需的,因为此编码支持将ASCII字符字节(单字节编码)与GB中文字符字节(双字节编码)混合。转义序列标记不应解释为ASCII的区域。
如果您选择使用hz-gb-2312
编码,则必须自行删除任何不需要的转义序列,如果您认为不需要它们。但是,也许你确实需要它们。你必须弄清楚你的打印机到底想要什么。
或者,如果你真的不想拥有那些转义序列,并且如果你不担心必须处理ASCII字符,并且相信你只需要处理中文双字节字符,那么你可以选择坚持使用vanilla GB2312
编码,然后自己删除每个字节的最高位,实际上将结果转换为7位编码。
以下是代码的外观。请注意,我使用0x7F
屏蔽每个字节值以丢弃第8位。
static void Main(string[] args)
{
const string SimplifiedChineseChars = "冈区色呆";
byte[] bytes = Encoding.GetEncoding("gb2312") // vanilla gb2312 encoding
.GetBytes(SimplifiedChineseChars)
.Select(b => (byte)(b & 0x7F)) // retain 7 bits only
.ToArray();
string hex = BitConverter.ToString(bytes).Replace("-", "_");
Console.WriteLine(hex);
}
输出:
38_54_47_78_49_2B_34_74