C#中简体中文转十六进制GB2312编码

Chinese Simplified to Hex GB2312 encoding in C#

我在尝试将包含简体中文的字符串转换为双字节编码 (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
        }

对我来说唯一有意义的是 38_54_47_78_49_2b_34_74 是某种形式的 7 位编码。

有趣的是,确实存在 GB2312 编码的 7 位版本,称为 HZ 字符编码。

这里是wikipedia entry on HZ。有趣的部分:

The HZ ... encoding was invented to facilitate the use of Chinese characters through e-mail, which at that time only allowed 7-bit characters.

the HZ code uses only printable, 7-bit characters to represent Chinese characters.

并且,根据 this Microsoft reference page on EncodingInfo.GetEncoding,.NET 支持此字符编码:

52936 hz-gb-2312 Chinese Simplified (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